From 269692c70cedaf7cf98c5964a9f27387f5d41f73 Mon Sep 17 00:00:00 2001 From: lancegin Date: Thu, 29 Jun 2017 17:21:34 +0800 Subject: [PATCH] add: require jssha and nibbler --- package.json | 3 + src/nibbler/nibbler.js | 245 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 src/nibbler/nibbler.js diff --git a/package.json b/package.json index fbd92f4..f93682e 100644 --- a/package.json +++ b/package.json @@ -34,5 +34,8 @@ "babel-preset-es2015": "^6.24.1", "babel-preset-stage-0": "^6.24.1", "mocha": "^3.4.2" + }, + "dependencies": { + "jssha": "^2.3.1" } } diff --git a/src/nibbler/nibbler.js b/src/nibbler/nibbler.js new file mode 100644 index 0000000..c8611a3 --- /dev/null +++ b/src/nibbler/nibbler.js @@ -0,0 +1,245 @@ +/* +Adapted for Node.js by Matt Robenolt +Reference: http://www.tumuski.com/2010/04/nibbler/ +*/ + +/** + * Node.js example: + * + * var nibbler = require('nibbler'); + * + * nibbler.b32encode('Hello, World!'); // returns JBSWY3DPFQQFO33SNRSCC=====' + * nibbler.b32decode('JBSWY3DPFQQFO33SNRSCC====='); // returns 'Hello, World!' + * nibbler.b64encode('Hello, World!'); // returns 'SGVsbG8sIFdvcmxkIQ==' + * nibbler.b64decode('SGVsbG8sIFdvcmxkIQ=='); // returns 'Hello, World!' + */ + +/* +Copyright (c) 2010 Thomas Peri +http://www.tumuski.com/ +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, + eqeqeq: true, plusplus: true, regexp: true, newcap: true, immed: true */ +// (good parts minus bitwise and strict, plus white.) + +/** + * Nibbler - Multi-Base Encoder + * + * version 2010-04-07 + * + * Options: + * dataBits: The number of bits in each character of unencoded data. + * codeBits: The number of bits in each character of encoded data. + * keyString: The characters that correspond to each value when encoded. + * pad (optional): The character to pad the end of encoded output. + * arrayData (optional): If truthy, unencoded data is an array instead of a string. + * + * Example: + * + * var base64_8bit = new Nibbler({ + * dataBits: 8, + * codeBits: 6, + * keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + * pad: '=' + * }); + * base64_8bit.encode("Hello, World!"); // returns "SGVsbG8sIFdvcmxkIQ==" + * base64_8bit.decode("SGVsbG8sIFdvcmxkIQ=="); // returns "Hello, World!" + * + * var base64_7bit = new Nibbler({ + * dataBits: 7, + * codeBits: 6, + * keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + * pad: '=' + * }); + * base64_7bit.encode("Hello, World!"); // returns "kZdmzesQV9/LZkQg==" + * base64_7bit.decode("kZdmzesQV9/LZkQg=="); // returns "Hello, World!" + * + */ +var Nibbler = function (options) { + var construct, + + // options + pad, dataBits, codeBits, keyString, arrayData, + + // private instance variables + mask, group, max, + + // private methods + gcd, translate, + + // public methods + encode, decode; + + // pseudo-constructor + construct = function () { + var i, mag, prev; + + // options + pad = options.pad || ''; + dataBits = options.dataBits; + codeBits = options.codeBits; + keyString = options.keyString; + arrayData = options.arrayData; + + // bitmasks + mag = Math.max(dataBits, codeBits); + prev = 0; + mask = []; + for (i = 0; i < mag; i += 1) { + mask.push(prev); + prev += prev + 1; + } + max = prev; + + // ouput code characters in multiples of this number + group = dataBits / gcd(dataBits, codeBits); + }; + + // greatest common divisor + gcd = function (a, b) { + var t; + while (b !== 0) { + t = b; + b = a % b; + a = t; + } + return a; + }; + + // the re-coder + translate = function (input, bitsIn, bitsOut, decoding) { + var i, len, chr, byteIn, + buffer, size, output, + write; + + // append a byte to the output + write = function (n) { + if (!decoding) { + output.push(keyString.charAt(n)); + } else if (arrayData) { + output.push(n); + } else { + output.push(String.fromCharCode(n)); + } + }; + + buffer = 0; + size = 0; + output = []; + + len = input.length; + for (i = 0; i < len; i += 1) { + // the new size the buffer will be after adding these bits + size += bitsIn; + + // read a character + if (decoding) { + // decode it + chr = input.charAt(i); + byteIn = keyString.indexOf(chr); + if (chr === pad) { + break; + } else if (byteIn < 0) { + throw 'the character "' + chr + '" is not a member of ' + keyString; + } + } else { + if (arrayData) { + byteIn = input[i]; + } else { + byteIn = input.charCodeAt(i); + } + if ((byteIn | max) !== max) { + throw byteIn + " is outside the range 0-" + max; + } + } + + // shift the buffer to the left and add the new bits + buffer = (buffer << bitsIn) | byteIn; + + // as long as there's enough in the buffer for another output... + while (size >= bitsOut) { + // the new size the buffer will be after an output + size -= bitsOut; + + // output the part that lies to the left of that number of bits + // by shifting the them to the right + write(buffer >> size); + + // remove the bits we wrote from the buffer + // by applying a mask with the new size + buffer &= mask[size]; + } + } + + // If we're encoding and there's input left over, pad the output. + // Otherwise, leave the extra bits off, 'cause they themselves are padding + if (!decoding && size > 0) { + + // flush the buffer + write(buffer << (bitsOut - size)); + + // add padding keyString for the remainder of the group + len = output.length % group; + for (i = 0; i < len; i += 1) { + output.push(pad); + } + } + + // string! + return (arrayData && decoding) ? output : output.join(''); + }; + + /** + * Encode. Input and output are strings. + */ + encode = function (input) { + return translate(input, dataBits, codeBits, false); + }; + + /** + * Decode. Input and output are strings. + */ + decode = function (input) { + return translate(input, codeBits, dataBits, true); + }; + + this.encode = encode; + this.decode = decode; + construct(); +}; + +var Base32 = new Nibbler({ + dataBits: 8, + codeBits: 5, + keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', + pad: '=' +}); +var Base64 = new Nibbler({ + dataBits: 8, + codeBits: 6, + keyString: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + pad: '=' +}); + +exports.Nibbler = Nibbler; +exports.b32encode = Base32.encode; +exports.b32decode = Base32.decode; +exports.b64encode = Base64.encode; +exports.b64decode = Base64.decode; \ No newline at end of file