123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- /*
- * [hi-base32]{@link https://github.com/emn178/hi-base32}
- *
- * @version 0.5.0
- * @author Chen, Yi-Cyuan [emn178@gmail.com]
- * @copyright Chen, Yi-Cyuan 2015-2018
- * @license MIT
- */
- /*jslint bitwise: true */
- (function () {
- 'use strict';
- var root = typeof window === 'object' ? window : {};
- var NODE_JS = !root.HI_BASE32_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
- if (NODE_JS) {
- root = global;
- }
- var COMMON_JS = !root.HI_BASE32_NO_COMMON_JS && typeof module === 'object' && module.exports;
- var AMD = typeof define === 'function' && define.amd;
- var BASE32_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.split('');
- var BASE32_DECODE_CHAR = {
- 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8,
- 'J': 9, 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16,
- 'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24,
- 'Z': 25, '2': 26, '3': 27, '4': 28, '5': 29, '6': 30, '7': 31
- };
- var blocks = [0, 0, 0, 0, 0, 0, 0, 0];
- var throwInvalidUtf8 = function (position, partial) {
- if (partial.length > 10) {
- partial = '...' + partial.substr(-10);
- }
- var err = new Error('Decoded data is not valid UTF-8.'
- + ' Maybe try base32.decode.asBytes()?'
- + ' Partial data after reading ' + position + ' bytes: ' + partial + ' <-');
- err.position = position;
- throw err;
- };
- var toUtf8String = function (bytes) {
- var str = '', length = bytes.length, i = 0, followingChars = 0, b, c;
- while (i < length) {
- b = bytes[i++];
- if (b <= 0x7F) {
- str += String.fromCharCode(b);
- continue;
- } else if (b > 0xBF && b <= 0xDF) {
- c = b & 0x1F;
- followingChars = 1;
- } else if (b <= 0xEF) {
- c = b & 0x0F;
- followingChars = 2;
- } else if (b <= 0xF7) {
- c = b & 0x07;
- followingChars = 3;
- } else {
- throwInvalidUtf8(i, str);
- }
- for (var j = 0; j < followingChars; ++j) {
- b = bytes[i++];
- if (b < 0x80 || b > 0xBF) {
- throwInvalidUtf8(i, str);
- }
- c <<= 6;
- c += b & 0x3F;
- }
- if (c >= 0xD800 && c <= 0xDFFF) {
- throwInvalidUtf8(i, str);
- }
- if (c > 0x10FFFF) {
- throwInvalidUtf8(i, str);
- }
- if (c <= 0xFFFF) {
- str += String.fromCharCode(c);
- } else {
- c -= 0x10000;
- str += String.fromCharCode((c >> 10) + 0xD800);
- str += String.fromCharCode((c & 0x3FF) + 0xDC00);
- }
- }
- return str;
- };
- var decodeAsBytes = function (base32Str) {
- if (!/^[A-Z2-7=]+$/.test(base32Str)) {
- throw new Error('Invalid base32 characters');
- }
- base32Str = base32Str.replace(/=/g, '');
- var v1, v2, v3, v4, v5, v6, v7, v8, bytes = [], index = 0, length = base32Str.length;
- // 4 char to 3 bytes
- for (var i = 0, count = length >> 3 << 3; i < count;) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v6 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v7 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v8 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
- bytes[index++] = (v2 << 6 | v3 << 1 | v4 >>> 4) & 255;
- bytes[index++] = (v4 << 4 | v5 >>> 1) & 255;
- bytes[index++] = (v5 << 7 | v6 << 2 | v7 >>> 3) & 255;
- bytes[index++] = (v7 << 5 | v8) & 255;
- }
- // remain bytes
- var remain = length - count;
- if (remain === 2) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
- } else if (remain === 4) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
- bytes[index++] = (v2 << 6 | v3 << 1 | v4 >>> 4) & 255;
- } else if (remain === 5) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
- bytes[index++] = (v2 << 6 | v3 << 1 | v4 >>> 4) & 255;
- bytes[index++] = (v4 << 4 | v5 >>> 1) & 255;
- } else if (remain === 7) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v6 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v7 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
- bytes[index++] = (v2 << 6 | v3 << 1 | v4 >>> 4) & 255;
- bytes[index++] = (v4 << 4 | v5 >>> 1) & 255;
- bytes[index++] = (v5 << 7 | v6 << 2 | v7 >>> 3) & 255;
- }
- return bytes;
- };
- var encodeAscii = function (str) {
- var v1, v2, v3, v4, v5, base32Str = '', length = str.length;
- for (var i = 0, count = parseInt(length / 5) * 5; i < count;) {
- v1 = str.charCodeAt(i++);
- v2 = str.charCodeAt(i++);
- v3 = str.charCodeAt(i++);
- v4 = str.charCodeAt(i++);
- v5 = str.charCodeAt(i++);
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
- BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
- BASE32_ENCODE_CHAR[(v4 << 3 | v5 >>> 5) & 31] +
- BASE32_ENCODE_CHAR[v5 & 31];
- }
- // remain char
- var remain = length - count;
- if (remain === 1) {
- v1 = str.charCodeAt(i);
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2) & 31] +
- '======';
- } else if (remain === 2) {
- v1 = str.charCodeAt(i++);
- v2 = str.charCodeAt(i);
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4) & 31] +
- '====';
- } else if (remain === 3) {
- v1 = str.charCodeAt(i++);
- v2 = str.charCodeAt(i++);
- v3 = str.charCodeAt(i);
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1) & 31] +
- '===';
- } else if (remain === 4) {
- v1 = str.charCodeAt(i++);
- v2 = str.charCodeAt(i++);
- v3 = str.charCodeAt(i++);
- v4 = str.charCodeAt(i);
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
- BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
- BASE32_ENCODE_CHAR[(v4 << 3) & 31] +
- '=';
- }
- return base32Str;
- };
- var encodeUtf8 = function (str) {
- var v1, v2, v3, v4, v5, code, end = false, base32Str = '',
- index = 0, i, start = 0, bytes = 0, length = str.length;
- do {
- blocks[0] = blocks[5];
- blocks[1] = blocks[6];
- blocks[2] = blocks[7];
- for (i = start; index < length && i < 5; ++index) {
- code = str.charCodeAt(index);
- if (code < 0x80) {
- blocks[i++] = code;
- } else if (code < 0x800) {
- blocks[i++] = 0xc0 | (code >> 6);
- blocks[i++] = 0x80 | (code & 0x3f);
- } else if (code < 0xd800 || code >= 0xe000) {
- blocks[i++] = 0xe0 | (code >> 12);
- blocks[i++] = 0x80 | ((code >> 6) & 0x3f);
- blocks[i++] = 0x80 | (code & 0x3f);
- } else {
- code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(++index) & 0x3ff));
- blocks[i++] = 0xf0 | (code >> 18);
- blocks[i++] = 0x80 | ((code >> 12) & 0x3f);
- blocks[i++] = 0x80 | ((code >> 6) & 0x3f);
- blocks[i++] = 0x80 | (code & 0x3f);
- }
- }
- bytes += i - start;
- start = i - 5;
- if (index === length) {
- ++index;
- }
- if (index > length && i < 6) {
- end = true;
- }
- v1 = blocks[0];
- if (i > 4) {
- v2 = blocks[1];
- v3 = blocks[2];
- v4 = blocks[3];
- v5 = blocks[4];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
- BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
- BASE32_ENCODE_CHAR[(v4 << 3 | v5 >>> 5) & 31] +
- BASE32_ENCODE_CHAR[v5 & 31];
- } else if (i === 1) {
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2) & 31] +
- '======';
- } else if (i === 2) {
- v2 = blocks[1];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4) & 31] +
- '====';
- } else if (i === 3) {
- v2 = blocks[1];
- v3 = blocks[2];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1) & 31] +
- '===';
- } else {
- v2 = blocks[1];
- v3 = blocks[2];
- v4 = blocks[3];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
- BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
- BASE32_ENCODE_CHAR[(v4 << 3) & 31] +
- '=';
- }
- } while (!end);
- return base32Str;
- };
- var encodeBytes = function (bytes) {
- var v1, v2, v3, v4, v5, base32Str = '', length = bytes.length;
- for (var i = 0, count = parseInt(length / 5) * 5; i < count;) {
- v1 = bytes[i++];
- v2 = bytes[i++];
- v3 = bytes[i++];
- v4 = bytes[i++];
- v5 = bytes[i++];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
- BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
- BASE32_ENCODE_CHAR[(v4 << 3 | v5 >>> 5) & 31] +
- BASE32_ENCODE_CHAR[v5 & 31];
- }
- // remain char
- var remain = length - count;
- if (remain === 1) {
- v1 = bytes[i];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2) & 31] +
- '======';
- } else if (remain === 2) {
- v1 = bytes[i++];
- v2 = bytes[i];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4) & 31] +
- '====';
- } else if (remain === 3) {
- v1 = bytes[i++];
- v2 = bytes[i++];
- v3 = bytes[i];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1) & 31] +
- '===';
- } else if (remain === 4) {
- v1 = bytes[i++];
- v2 = bytes[i++];
- v3 = bytes[i++];
- v4 = bytes[i];
- base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
- BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
- BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
- BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
- BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
- BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
- BASE32_ENCODE_CHAR[(v4 << 3) & 31] +
- '=';
- }
- return base32Str;
- };
- var encode = function (input, asciiOnly) {
- var notString = typeof(input) !== 'string';
- if (notString && input.constructor === ArrayBuffer) {
- input = new Uint8Array(input);
- }
- if (notString) {
- return encodeBytes(input);
- } else if (asciiOnly) {
- return encodeAscii(input);
- } else {
- return encodeUtf8(input);
- }
- };
- var decode = function (base32Str, asciiOnly) {
- if (!asciiOnly) {
- return toUtf8String(decodeAsBytes(base32Str));
- }
- if (!/^[A-Z2-7=]+$/.test(base32Str)) {
- throw new Error('Invalid base32 characters');
- }
- var v1, v2, v3, v4, v5, v6, v7, v8, str = '', length = base32Str.indexOf('=');
- if (length === -1) {
- length = base32Str.length;
- }
- // 8 char to 5 bytes
- for (var i = 0, count = length >> 3 << 3; i < count;) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v6 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v7 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v8 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255) +
- String.fromCharCode((v2 << 6 | v3 << 1 | v4 >>> 4) & 255) +
- String.fromCharCode((v4 << 4 | v5 >>> 1) & 255) +
- String.fromCharCode((v5 << 7 | v6 << 2 | v7 >>> 3) & 255) +
- String.fromCharCode((v7 << 5 | v8) & 255);
- }
- // remain bytes
- var remain = length - count;
- if (remain === 2) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255);
- } else if (remain === 4) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255) +
- String.fromCharCode((v2 << 6 | v3 << 1 | v4 >>> 4) & 255);
- } else if (remain === 5) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255) +
- String.fromCharCode((v2 << 6 | v3 << 1 | v4 >>> 4) & 255) +
- String.fromCharCode((v4 << 4 | v5 >>> 1) & 255);
- } else if (remain === 7) {
- v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v6 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- v7 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
- str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255) +
- String.fromCharCode((v2 << 6 | v3 << 1 | v4 >>> 4) & 255) +
- String.fromCharCode((v4 << 4 | v5 >>> 1) & 255) +
- String.fromCharCode((v5 << 7 | v6 << 2 | v7 >>> 3) & 255);
- }
- return str;
- };
- var exports = {
- encode: encode,
- decode: decode
- };
- decode.asBytes = decodeAsBytes;
- if (COMMON_JS) {
- module.exports = exports;
- } else {
- root.base32 = exports;
- if (AMD) {
- define(function() {
- return exports;
- });
- }
- }
- })();
|