diff --git a/src/common/base64.js b/src/common/base64.js index 5c0b3f4f7..06c39ff45 100644 --- a/src/common/base64.js +++ b/src/common/base64.js @@ -23,7 +23,7 @@ var base64 = exports; base64.fromArrayBuffer = function (arrayBuffer) { var array = new Uint8Array(arrayBuffer); - return uint8ToBase64(array); + return btoa(bytesToBinaryString(array)); }; base64.toArrayBuffer = function (str) { @@ -36,46 +36,12 @@ base64.toArrayBuffer = function (str) { return arrayBuffer; }; -// ------------------------------------------------------------------------------ - -/* This code is based on the performance tests at http://jsperf.com/b64tests - * This 12-bit-at-a-time algorithm was the best performing version on all - * platforms tested. - */ - -var b64_6bit = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; -var b64_12bit; - -var b64_12bitTable = function () { - b64_12bit = []; - for (var i = 0; i < 64; i++) { - for (var j = 0; j < 64; j++) { - b64_12bit[i * 64 + j] = b64_6bit[i] + b64_6bit[j]; - } - } - b64_12bitTable = function () { return b64_12bit; }; - return b64_12bit; -}; - -function uint8ToBase64 (rawData) { - var numBytes = rawData.byteLength; - var output = ''; - var segment; - var table = b64_12bitTable(); - for (var i = 0; i < numBytes - 2; i += 3) { - segment = (rawData[i] << 16) + (rawData[i + 1] << 8) + rawData[i + 2]; - output += table[segment >> 12]; - output += table[segment & 0xfff]; - } - if (numBytes - i === 2) { - segment = (rawData[i] << 16) + (rawData[i + 1] << 8); - output += table[segment >> 12]; - output += b64_6bit[(segment & 0xfff) >> 6]; - output += '='; - } else if (numBytes - i === 1) { - segment = (rawData[i] << 16); - output += table[segment >> 12]; - output += '=='; +function bytesToBinaryString (bytes) { + var CHUNK_SIZE = 1 << 15; + var string = ''; + for (var i = 0; i < bytes.length; i += CHUNK_SIZE) { + var chunk = bytes.subarray(i, i + CHUNK_SIZE); + string += String.fromCharCode.apply(null, chunk); } - return output; + return string; } diff --git a/test/test.base64.js b/test/test.base64.js index a326a5e75..1f7e726c6 100644 --- a/test/test.base64.js +++ b/test/test.base64.js @@ -53,6 +53,14 @@ describe('base64', function () { ); }); + it('can base64 encode big files reasonably fast', function () { + var bytes = Uint8Array.from({ length: 1 << 24 }, (v, i) => i & 0xff); + + var start = Date.now(); + base64.fromArrayBuffer(bytes.buffer); + expect(Date.now() - start).toBeLessThan(1000); + }); + it('Test#003 : can base64 encode an text string in an ArrayBuffer', function () { var orig = 'Some Awesome Test This Is!'; var base64string = btoa(orig);