/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla XML-RPC Client component. * * The Initial Developer of the Original Code is * Digital Creations 2, Inc. * Portions created by the Initial Developer are Copyright (C) 2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Martijn Pieters (original author) * Samuel Sieb * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ // From: http://lxr.mozilla.org/mozilla/source/extensions/xml-rpc/src/nsXmlRpcClient.js#956 /* Convert data (an array of integers) to a Base64 string. */ const toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; const base64Pad = '='; function toBase64(data) { let result = ''; const length = data.length; let i; // Convert every three bytes to 4 ascii characters. for (i = 0; i < (length - 2) ; i += 3) { result += toBase64Table[data.charCodeAt(i) >> 2]; result += toBase64Table[((data.charCodeAt(i) & 0x03) << 4) + (data.charCodeAt(i + 1) >> 4)]; result += toBase64Table[((data.charCodeAt(i + 1) & 0x0f) << 2) + (data.charCodeAt(i + 2) >> 6)]; result += toBase64Table[data.charCodeAt(i + 2) & 0x3f]; } // Convert the remaining 1 or 2 bytes, pad out to 4 characters. if (length % 3) { i = length - (length % 3); result += toBase64Table[data.charCodeAt(i) >> 2]; if ((length % 3) == 2) { result += toBase64Table[((data.charCodeAt(i) & 0x03) << 4) + (data.chartCodeAt(i + 1) >> 4)]; result += toBase64Table[(data.charCodeAt(i + 1) & 0x0f) << 2]; result += base64Pad; } else { result += toBase64Table[(data.charCodeAt(i) & 0x03) << 4]; result += base64Pad + base64Pad; } } return result; } /* Convert Base64 data to a string */ const toBinaryTable = [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 ]; const base64ToString = data => { let result = ''; let leftbits = 0; // number of bits decoded, but yet to be appended let leftdata = 0; // bits decoded, but yet to be appended // Convert one by one. for (let i = 0; i < data.length; i++) { const c = toBinaryTable[data.charCodeAt(i) & 0x7f]; const padding = (data.charCodeAt(i) == base64Pad.charCodeAt(0)); // Skip illegal characters and whitespace if (c == -1) continue; // Collect data into leftdata, update bitcount leftdata = (leftdata << 6) | c; leftbits += 6; // If we have 8 or more bits, append 8 bits to the result if (leftbits >= 8) { leftbits -= 8; // Append if not padding. if (!padding) result += String.fromCharCode((leftdata >> leftbits) & 0xff); leftdata &= (1 << leftbits) - 1; } } // If there are any bits left, the base64 string was corrupted if (leftbits) throw Components.Exception('Corrupted base64 string'); return result; }; startTest("dromaeo-string-base64", '09340c18'); let str = []; for (let i = 0; i < 4096; i++) str.push(String.fromCharCode((25 * Math.random()) + 97)); str = str.join(""); str += str; str += str; let base64; test("Convert String to Base 64", () => { base64 = toBase64(str); }); prep(() => { if (!base64) base64 = toBase64(str); }); test("Convert Base 64 to String", () => { if (str !== base64ToString(base64)) { throw "String conversion mis-match."; } }); endTest();