Comparing version 0.0.2 to 0.0.3
150
index.js
@@ -1,2 +0,2 @@ | ||
let assert = require('assert') | ||
'use strict' | ||
let ALPHABET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l' | ||
@@ -6,4 +6,4 @@ | ||
let ALPHABET_MAP = {} | ||
for (var z = 0; z < ALPHABET.length; z++) { | ||
var x = ALPHABET.charAt(z) | ||
for (let z = 0; z < ALPHABET.length; z++) { | ||
let x = ALPHABET.charAt(z) | ||
@@ -24,60 +24,31 @@ if (ALPHABET_MAP[x] !== undefined) throw new TypeError(x + ' is ambiguous') | ||
function convertbits (data, inbits, outbits, pad) { | ||
let val = 0 | ||
let bits = 0 | ||
let maxv = (1 << outbits) - 1 | ||
let ret = [] | ||
for (let i = 0; i < data.length; ++i) { | ||
val = (val << inbits) | data[i] | ||
bits += inbits | ||
while (bits >= outbits) { | ||
bits -= outbits | ||
ret.push((val >> bits) & maxv) | ||
} | ||
} | ||
if (pad) { | ||
if (bits > 0) { | ||
ret.push((val << (outbits - bits)) & maxv) | ||
} | ||
} else { | ||
// assert(!((val << (outbits - bits)) & maxv)) | ||
// assert(bits < inbits) | ||
} | ||
return ret | ||
} | ||
function encode (prefix, data) { | ||
data = Buffer.from(convertbits(data, 8, 5, true)) | ||
// too long? | ||
assert((prefix.length + 7 + data.length) <= 90) | ||
// determine chk mod | ||
function prefixChk (prefix) { | ||
let chk = 1 | ||
for (let i = 0; i < prefix.length; ++i) { | ||
let c = prefix.charCodeAt(i) >> 5 | ||
assert.notEqual(c, 0) | ||
let c = prefix.charCodeAt(i) | ||
if (c < 33 || c > 126) throw new Error('Invalid prefix (' + prefix + ')') | ||
chk = polymodStep(chk) ^ c | ||
chk = polymodStep(chk) ^ (c >> 5) | ||
} | ||
chk = polymodStep(chk) | ||
let result = '' | ||
for (let i = 0; i < prefix.length; ++i) { | ||
let c = prefix.charAt(i) | ||
let v = prefix.charCodeAt(i) | ||
chk = polymodStep(chk) ^ (v & 0x1f) | ||
result += c | ||
} | ||
result += '1' | ||
return chk | ||
} | ||
for (let i = 0; i < data.length; ++i) { | ||
let x = data[i] | ||
assert.equal(x >> 5, 0) | ||
function encode (prefix, words) { | ||
// too long? | ||
if ((prefix.length + 7 + words.length) > 90) throw new TypeError('Exceeds Bech32 maximum length') | ||
prefix = prefix.toLowerCase() | ||
// determine chk mod | ||
let chk = prefixChk(prefix) | ||
let result = prefix + '1' | ||
for (let i = 0; i < words.length; ++i) { | ||
let x = words[i] | ||
if ((x >> 5) !== 0) throw new Error('Non 5-bit word') | ||
chk = polymodStep(chk) ^ x | ||
@@ -101,54 +72,71 @@ result += ALPHABET.charAt(x) | ||
function decode (str) { | ||
assert(str.length >= 8) | ||
assert(str.length <= 90) | ||
if (str.length < 8) throw new TypeError(str + ' too short') | ||
if (str.length > 90) throw new TypeError(str + ' too long') | ||
// don't allow mixed case | ||
let lowered = str.toLowerCase() | ||
assert.equal(str, lowered) | ||
let uppered = str.toUpperCase() | ||
if (str !== lowered && str !== uppered) throw new Error('Mixed-case string ' + str) | ||
str = lowered | ||
let split = str.lastIndexOf('1') | ||
if (split === 0) throw new Error('Missing prefix for ' + str) | ||
let prefix = str.slice(0, split) | ||
let data = str.slice(split + 1) | ||
assert(prefix.length >= 1) | ||
assert(data.length >= 6) | ||
let wordChars = str.slice(split + 1) | ||
if (wordChars.length < 6) throw new Error('Data too short') | ||
let chk = 1 | ||
for (let i = 0; i < prefix.length; ++i) { | ||
let c = prefix.charCodeAt(i) | ||
assert(c >= 33 && c <= 126) | ||
let chk = prefixChk(prefix) | ||
let words = [] | ||
for (let i = 0; i < wordChars.length; ++i) { | ||
let c = wordChars.charAt(i) | ||
let v = ALPHABET_MAP[c] | ||
if (v === undefined) throw new Error('Unknown character ' + c) | ||
chk = polymodStep(chk) ^ v | ||
chk = polymodStep(chk) ^ (c >> 5) | ||
// not in the checksum? | ||
if (i + 6 >= wordChars.length) continue | ||
words.push(v) | ||
} | ||
chk = polymodStep(chk) | ||
for (let i = 0; i < prefix.length; ++i) { | ||
let c = prefix.charCodeAt(i) | ||
chk = polymodStep(chk) ^ (c & 0x1f) | ||
} | ||
if (chk !== 1) throw new Error('Invalid checksum for ' + str) | ||
return { prefix, words } | ||
} | ||
// NOTE: zero-fill required | ||
let result = Buffer.alloc(data.length) | ||
function convert (data, inBits, outBits, pad) { | ||
let value = 0 | ||
let bits = 0 | ||
let maxV = (1 << outBits) - 1 | ||
let result = [] | ||
for (let i = 0; i < data.length; ++i) { | ||
let cv = data.charCodeAt(i) | ||
assert.equal(cv & 0x80, 0) | ||
value = (value << inBits) | data[i] | ||
bits += inBits | ||
let c = data.charAt(i) | ||
let v = ALPHABET_MAP[c] | ||
assert.notEqual(v, undefined) | ||
while (bits >= outBits) { | ||
bits -= outBits | ||
result.push((value >> bits) & maxV) | ||
} | ||
} | ||
chk = polymodStep(chk) ^ v | ||
// not in the checksum? | ||
if (i + 6 < data.length) { | ||
result.writeUInt8(v, i) | ||
if (pad) { | ||
if (bits > 0) { | ||
result.push((value << (outBits - bits)) & maxV) | ||
} | ||
} else { | ||
if (bits >= inBits) throw new Error('Excess padding') | ||
if ((value << (outBits - bits)) & maxV) throw new Error('Non-zero padding') | ||
} | ||
assert.equal(chk & 0x1, 1) | ||
result = Buffer.from(convertbits(result.slice(0, -3), 5, 8, false)).slice(0, -1) | ||
return result | ||
} | ||
return { prefix, data: result } | ||
function toWords (bytes) { | ||
return convert(bytes, 8, 5, true) | ||
} | ||
module.exports = { decode, encode } | ||
function fromWords (words) { | ||
return convert(words, 5, 8, false) | ||
} | ||
module.exports = { decode, encode, toWords, fromWords } |
{ | ||
"name": "bech32", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Bech32 encoding / decoding", | ||
@@ -23,4 +23,6 @@ "keywords": [ | ||
"devDependencies": { | ||
"nyc": "^10.2.0", | ||
"standard": "*", | ||
"tape": "^4.6.3" | ||
"tape": "^4.6.3", | ||
"tap-dot": "*" | ||
}, | ||
@@ -32,5 +34,6 @@ "repository": { | ||
"scripts": { | ||
"coverage": "nyc --check-coverage --branches 90 --functions 90 tape test/*.js", | ||
"standard": "standard", | ||
"test": "tape test/index.js | tap-dot" | ||
"test": "tape test/*.js | tap-dot" | ||
} | ||
} |
@@ -5,3 +5,3 @@ # bech32 | ||
A [BIP???](https://github.com/sipa/bech32/blob/master/bip-witaddr.mediawiki#acknowledgements) compatible Bech32 encoding/decoding library. | ||
A [BIP173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) compatible Bech32 encoding/decoding library. | ||
@@ -17,5 +17,5 @@ | ||
## Credits | ||
- [Peter Wuille](https://github.com/sipa/bech32) for the reference JavaScript implementation, and for authoring the Bech32 [BIP](https://github.com/sipa/bech32/blob/master/bip-witaddr.mediawiki#acknowledgements). | ||
- [Peter Wuille](https://github.com/sipa/bech32) for the reference JavaScript implementation, and for authoring the Bech32 [BIP173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki). | ||
## License [MIT](LICENSE) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4768
4
112