bech32.js (5161B)
1 var ALPHABET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; 2 var ALPHABET_MAP = {}; 3 for (var z = 0; z < ALPHABET.length; z++) { 4 var x = ALPHABET.charAt(z); 5 ALPHABET_MAP[x] = z; 6 } 7 function polymodStep(pre) { 8 var b = pre >> 25; 9 return (((pre & 0x1ffffff) << 5) ^ 10 (-((b >> 0) & 1) & 0x3b6a57b2) ^ 11 (-((b >> 1) & 1) & 0x26508e6d) ^ 12 (-((b >> 2) & 1) & 0x1ea119fa) ^ 13 (-((b >> 3) & 1) & 0x3d4233dd) ^ 14 (-((b >> 4) & 1) & 0x2a1462b3)); 15 } 16 function prefixChk(prefix) { 17 var chk = 1; 18 for (var i = 0; i < prefix.length; ++i) { 19 var c = prefix.charCodeAt(i); 20 if (c < 33 || c > 126) 21 return 'Invalid prefix (' + prefix + ')'; 22 chk = polymodStep(chk) ^ (c >> 5); 23 } 24 chk = polymodStep(chk); 25 for (var i = 0; i < prefix.length; ++i) { 26 var v = prefix.charCodeAt(i); 27 chk = polymodStep(chk) ^ (v & 0x1f); 28 } 29 return chk; 30 } 31 function convertbits(data, inBits, outBits, pad) { 32 var value = 0; 33 var bits = 0; 34 var maxV = (1 << outBits) - 1; 35 var result = []; 36 for (var i = 0; i < data.length; ++i) { 37 value = (value << inBits) | data[i]; 38 bits += inBits; 39 while (bits >= outBits) { 40 bits -= outBits; 41 result.push((value >> bits) & maxV); 42 } 43 } 44 if (pad) { 45 if (bits > 0) { 46 result.push((value << (outBits - bits)) & maxV); 47 } 48 } 49 else { 50 if (bits >= inBits) 51 return 'Excess padding'; 52 if ((value << (outBits - bits)) & maxV) 53 return 'Non-zero padding'; 54 } 55 return result; 56 } 57 function toWords(bytes) { 58 return convertbits(bytes, 8, 5, true); 59 } 60 function fromWordsUnsafe(words) { 61 var res = convertbits(words, 5, 8, false); 62 if (Array.isArray(res)) 63 return res; 64 } 65 function fromWords(words) { 66 var res = convertbits(words, 5, 8, false); 67 if (Array.isArray(res)) 68 return res; 69 throw new Error(res); 70 } 71 function getLibraryFromEncoding(encoding) { 72 var ENCODING_CONST; 73 if (encoding === 'bech32') { 74 ENCODING_CONST = 1; 75 } 76 else { 77 ENCODING_CONST = 0x2bc830a3; 78 } 79 function encode(prefix, words, LIMIT) { 80 LIMIT = LIMIT || 90; 81 if (prefix.length + 7 + words.length > LIMIT) 82 throw new TypeError('Exceeds length limit'); 83 prefix = prefix.toLowerCase(); 84 // determine chk mod 85 var chk = prefixChk(prefix); 86 if (typeof chk === 'string') 87 throw new Error(chk); 88 var result = prefix + '1'; 89 for (var i = 0; i < words.length; ++i) { 90 var x = words[i]; 91 if (x >> 5 !== 0) 92 throw new Error('Non 5-bit word'); 93 chk = polymodStep(chk) ^ x; 94 result += ALPHABET.charAt(x); 95 } 96 for (var i = 0; i < 6; ++i) { 97 chk = polymodStep(chk); 98 } 99 chk ^= ENCODING_CONST; 100 for (var i = 0; i < 6; ++i) { 101 var v = (chk >> ((5 - i) * 5)) & 0x1f; 102 result += ALPHABET.charAt(v); 103 } 104 return result; 105 } 106 function __decode(str, LIMIT) { 107 LIMIT = LIMIT || 90; 108 if (str.length < 8) 109 return str + ' too short'; 110 if (str.length > LIMIT) 111 return 'Exceeds length limit'; 112 // don't allow mixed case 113 var lowered = str.toLowerCase(); 114 var uppered = str.toUpperCase(); 115 if (str !== lowered && str !== uppered) 116 return 'Mixed-case string ' + str; 117 str = lowered; 118 var split = str.lastIndexOf('1'); 119 if (split === -1) 120 return 'No separator character for ' + str; 121 if (split === 0) 122 return 'Missing prefix for ' + str; 123 var prefix = str.slice(0, split); 124 var wordChars = str.slice(split + 1); 125 if (wordChars.length < 6) 126 return 'Data too short'; 127 var chk = prefixChk(prefix); 128 if (typeof chk === 'string') 129 return chk; 130 var words = []; 131 for (var i = 0; i < wordChars.length; ++i) { 132 var c = wordChars.charAt(i); 133 var v = ALPHABET_MAP[c]; 134 if (v === undefined) 135 return 'Unknown character ' + c; 136 chk = polymodStep(chk) ^ v; 137 // not in the checksum? 138 if (i + 6 >= wordChars.length) 139 continue; 140 words.push(v); 141 } 142 if (chk !== ENCODING_CONST) 143 return 'Invalid checksum for ' + str; 144 return { prefix: prefix, words: words }; 145 } 146 function decodeUnsafe(str, LIMIT) { 147 var res = __decode(str, LIMIT); 148 if (typeof res === 'object') 149 return res; 150 } 151 function decode(str, LIMIT) { 152 var res = __decode(str, LIMIT); 153 if (typeof res === 'object') 154 return res; 155 throw new Error(res); 156 } 157 return { 158 decodeUnsafe: decodeUnsafe, 159 decode: decode, 160 encode: encode, 161 toWords: toWords, 162 fromWordsUnsafe: fromWordsUnsafe, 163 fromWords: fromWords 164 }; 165 } 166 167 const bech32 = getLibraryFromEncoding('bech32'); 168 const bech32m = getLibraryFromEncoding('bech32m');