Skip to content

Commit d78ebd5

Browse files
committed
Add base32 codec
1 parent 235f818 commit d78ebd5

2 files changed

Lines changed: 76 additions & 0 deletions

File tree

‎lib/base32.js‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict'
2+
3+
const { transcode } = require('./transcode')
4+
const utf8 = require('./utf8')
5+
6+
const Base32 = {
7+
encode (buf) {
8+
let str = transcode(8, 5, buf, bitsToChar)
9+
return utf8.encode(str)
10+
},
11+
12+
decode (str) {
13+
let buf = utf8.decode(str)
14+
return transcode(5, 8, buf, charToBits)
15+
}
16+
}
17+
18+
// input | char | code
19+
// ------------+-----------+-----------
20+
// 00 - 19 | A - Z | 41 - 5a
21+
// | a - z | 61 - 7a
22+
// 1a - 1f | 2 - 7 | 32 - 37
23+
24+
function bitsToChar (b) {
25+
return ~((b - 0x00) | (0x19 - b)) >> 8 & (b + 0x41) // 0x41 - 0x00
26+
| ~((b - 0x1a) | (0x1f - b)) >> 8 & (b + 0x18) // 0x32 - 0x1a
27+
}
28+
29+
function charToBits (c) {
30+
return ~((c - 0x41) | (0x5a - c)) >> 8 & (c - 0x41) // 0x00 - 0x41
31+
| ~((c - 0x61) | (0x7a - c)) >> 8 & (c - 0x61) // 0x00 - 0x61
32+
| ~((c - 0x32) | (0x37 - c)) >> 8 & (c - 0x18) // 0x1a - 0x32
33+
}
34+
35+
module.exports = Base32

‎test/base32_test.js‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict'
2+
3+
const base32 = require('../lib/base32')
4+
const { randomBytes, assertBuffer, HELLO_WORLD } = require('./utils')
5+
const { assert } = require('chai')
6+
7+
describe('base32', () => {
8+
it('encodes to base32', () => {
9+
assert.equal(base32.encode(HELLO_WORLD), 'NBSWY3DPEB3W64TMMQ======')
10+
})
11+
12+
it('decodes a string from base32', () => {
13+
let buf = base32.decode('NBSWY3DPEB3W64TMMQ======')
14+
assertBuffer(buf, HELLO_WORLD)
15+
})
16+
17+
it('decodes from lowercase base32', () => {
18+
let buf = base32.decode('nbswy3dpeb3w64tmmq======')
19+
assertBuffer(buf, HELLO_WORLD)
20+
})
21+
22+
it('decodes arbitrary bytes from base32', () => {
23+
let buf = base32.decode('AAS5T6NYGDF72NPX')
24+
let bytes = [0x00, 0x25, 0xd9, 0xf9, 0xb8, 0x30, 0xcb, 0xfd, 0x35, 0xf7]
25+
assertBuffer(buf, bytes)
26+
assert.equal(base32.encode(buf), 'AAS5T6NYGDF72NPX')
27+
})
28+
29+
it('converts to and from base32', () => {
30+
for (let i = 0; i < 100; i++) {
31+
let buf = randomBytes(200)
32+
33+
let str = base32.encode(buf)
34+
assert.equal(str.length, 8 * Math.ceil(buf.length / 5))
35+
assert.match(str, /^[A-Z2-7]*={0,7}$/)
36+
37+
let parsed = base32.decode(str)
38+
assertBuffer(parsed, buf)
39+
}
40+
})
41+
})

0 commit comments

Comments
 (0)