From 0026f83e5a4acaecc33b203a466d8d8a32bf8465 Mon Sep 17 00:00:00 2001 From: Gregg Tavares Date: Fri, 12 Feb 2016 19:02:14 +0800 Subject: [PATCH 1/2] test for big data --- test/big-data.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 test/big-data.js diff --git a/test/big-data.js b/test/big-data.js new file mode 100644 index 0000000..59ad7f1 --- /dev/null +++ b/test/big-data.js @@ -0,0 +1,24 @@ +var test = require('tape') +var b64 = require('../lib/b64') + +test('convert big data to base64', function (t) { + var b64str, arr, i, length + var big = new Uint8Array(64 * 1024 * 1024) + for (i = 0, length = big.length; i < length; ++i) { + big[i] = i % 256 + } + b64str = b64.fromByteArray(big) + arr = b64.toByteArray(b64str) + t.ok(equal(arr, big)) + t.end() +}) + +function equal (a, b) { + var i + var length = a.length + if (length !== b.length) return false + for (i = 0; i < length; ++i) { + if (a[i] !== b[i]) return false + } + return true +} From 81dc9862e425173e11b3c95c9f8715bf6c1f1480 Mon Sep 17 00:00:00 2001 From: Gregg Tavares Date: Fri, 12 Feb 2016 19:02:29 +0800 Subject: [PATCH 2/2] fix to big data test --- lib/b64.js | 65 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/lib/b64.js b/lib/b64.js index 34a2aaf..ee5cb62 100644 --- a/lib/b64.js +++ b/lib/b64.js @@ -1,28 +1,23 @@ ;(function (exports) { 'use strict' - var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + var lookup = Array.prototype.map.call(code, function (c) { return c }) + var revLookup = [] + + for (var i = 0; i < code.length; ++i) { + revLookup[code.charCodeAt(i)] = i + } + revLookup['-'.charCodeAt(0)] = 62 + revLookup['_'.charCodeAt(0)] = 63 var Arr = (typeof Uint8Array !== 'undefined') ? Uint8Array : Array - var PLUS = '+'.charCodeAt(0) - var SLASH = '/'.charCodeAt(0) - var NUMBER = '0'.charCodeAt(0) - var LOWER = 'a'.charCodeAt(0) - var UPPER = 'A'.charCodeAt(0) - var PLUS_URL_SAFE = '-'.charCodeAt(0) - var SLASH_URL_SAFE = '_'.charCodeAt(0) - function decode (elt) { - var code = elt.charCodeAt(0) - if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+' - if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/' - if (code < NUMBER) return -1 // no match - if (code < NUMBER + 10) return code - NUMBER + 26 + 26 - if (code < UPPER + 26) return code - UPPER - if (code < LOWER + 26) return code - LOWER + 26 + var v = revLookup[elt.charCodeAt(0)] + return v !== undefined ? v : -1 } function b64ToByteArray (b64) { @@ -71,24 +66,36 @@ return arr } + function encode (num) { + return lookup[num] + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + function encodeChunk (uint8, start, end) { + var temp + var output = [] + for (var i = start; i < end; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output.push(tripletToBase64(temp)) + } + return output.join('') + } + function uint8ToBase64 (uint8) { var i var extraBytes = uint8.length % 3 // if we have 1 byte left, pad 2 bytes var output = '' + var parts = [] var temp, length - - function encode (num) { - return lookup.charAt(num) - } - - function tripletToBase64 (num) { - return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) - } + var maxChunkLength = 16383 // must be multiple of 3 // go through the array every three bytes, we'll deal with trailing stuff later - for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { - temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output += tripletToBase64(temp) + + for (i = 0, length = uint8.length - extraBytes; i < length; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > length ? length : (i + maxChunkLength))) } // pad the end with zeros, but make sure to not forget the extra bytes @@ -110,7 +117,9 @@ break } - return output + parts.push(output) + + return parts.join('') } exports.toByteArray = b64ToByteArray