Skip to content

Commit

Permalink
Merge pull request #16 from bitcoinjs/ext
Browse files Browse the repository at this point in the history
Remove length limits
  • Loading branch information
dcousens committed Dec 6, 2017
2 parents 2077fe0 + b5094cf commit 3ea9987
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
13 changes: 12 additions & 1 deletion README.md
Expand Up @@ -7,11 +7,22 @@ A [BIP173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) compa

## Example
``` javascript
let bech32 = require('bech32')


bech32.decode('abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw')
// => {
// prefix: 'abcdef',
// words: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
// }
```


### Advanced
BIP173 enforces a limitation of 90 characters, if extend the `LIMIT` parameter beyond this, be aware that the [effectiveness of checksum decreases as the length increases](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#checksum-design).

It is highly recommended **NOT** exceed 1023 characters, as the module could only guarantee detecting 1 error.


## Credits
- [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).

Expand Down
12 changes: 7 additions & 5 deletions index.js
Expand Up @@ -37,9 +37,10 @@ function prefixChk (prefix) {
return chk
}

function encode (prefix, words) {
// too long?
if ((prefix.length + 7 + words.length) > 90) throw new TypeError('Exceeds Bech32 maximum length')
function encode (prefix, words, LIMIT) {
LIMIT = LIMIT || 90
if ((prefix.length + 7 + words.length) > LIMIT) throw new TypeError('Exceeds length limit')

prefix = prefix.toLowerCase()

// determine chk mod
Expand All @@ -66,9 +67,10 @@ function encode (prefix, words) {
return result
}

function decode (str) {
function decode (str, LIMIT) {
LIMIT = LIMIT || 90
if (str.length < 8) throw new TypeError(str + ' too short')
if (str.length > 90) throw new TypeError(str + ' too long')
if (str.length > LIMIT) throw new TypeError('Exceeds length limit')

// don't allow mixed case
let lowered = str.toLowerCase()
Expand Down
23 changes: 20 additions & 3 deletions test/fixtures.json
Expand Up @@ -42,6 +42,13 @@
"prefix": "split",
"hex": "c5f38b70305f519bf66d85fb6cf03058f3dde463ecd7918f2dc743918f2d",
"words": [24,23,25,24,22,28,1,16,11,29,8,25,23,29,19,13,16,23,29,22,25,28,1,16,11,3,25,29,27,25,3,3,29,19,11,25,3,3,25,13,24,29,1,25,3,3,25,13]
},
{
"string": "11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq978ear",
"prefix": "1",
"hex": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"words": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
"limit": 300
}
],
"invalid": [
Expand All @@ -59,7 +66,7 @@
},
{
"string": "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",
"exception": "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx too long"
"exception": "Exceeds length limit"
},
{
"string": "x1b4n0q5v",
Expand Down Expand Up @@ -89,12 +96,22 @@
{
"prefix": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzfoobarfoobar",
"words": [128],
"exception": "Exceeds Bech32 maximum length"
"exception": "Exceeds length limit"
},
{
"prefix": "foobar",
"words": [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20],
"exception": "Exceeds Bech32 maximum length"
"exception": "Exceeds length limit"
},
{
"prefix": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzfoobarfoobarfoobarfoobar",
"words": [128],
"limit": 104,
"exception": "Exceeds length limit"
},
{
"string": "11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
"exception": "Exceeds length limit"
},
{
"prefix": "abc\u00ff",
Expand Down
8 changes: 3 additions & 5 deletions test/index.js
Expand Up @@ -15,14 +15,12 @@ fixtures.bech32.valid.forEach((f) => {

tape(`encode ${f.prefix} ${f.hex}`, (t) => {
t.plan(1)

t.strictEqual(bech32.encode(f.prefix, f.words), f.string.toLowerCase())
t.strictEqual(bech32.encode(f.prefix, f.words, f.limit), f.string.toLowerCase())
})

tape(`decode ${f.string}`, (t) => {
t.plan(1)

t.same(bech32.decode(f.string), {
t.same(bech32.decode(f.string, f.limit), {
prefix: f.prefix.toLowerCase(),
words: f.words
})
Expand All @@ -35,7 +33,7 @@ fixtures.bech32.valid.forEach((f) => {
buffer[f.string.lastIndexOf('1') + 1] ^= 0x1 // flip a bit, after the prefix
let string = buffer.toString('utf8')
t.throws(function () {
bech32.decode(string)
bech32.decode(string, f.limit)
}, new RegExp('Invalid checksum|Unknown character'))
})
})
Expand Down

0 comments on commit 3ea9987

Please sign in to comment.