[Edit]
+
0
-
0
JavaScript - JSON-safe Base94 encoding and decoding
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102// ⚠️ Warning: this source code contains proposition to Base94 encoding and decoding algorithm that may be used in JSONs as Base64 replacement. // License: you can use it for free for private and commercial, but do not remove information about author and source. // // Author: Grzegorz G. // Source: https://dirask.com/snippets/DNO7rp // indexes: 0 10 20 30 40 50 60 70 80 90 93 // | | | | | | | | | | | // v __ v v v v v __v v v v v const ALPHABET = ' !#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'; const CODES = {}; const VALUES = {}; for (let value = 0; value < ALPHABET.length; ++value) { const code = ALPHABET[value]; CODES[value] = code; VALUES[code] = value; } // Encodes bytes to Base94 string. // const encodeBase94 = (bytes) => { let base94 = ''; for (let k1 = 0, k2 = 0; k1 < bytes.length; k1 += 9, k2 += 11) { const limit1 = Math.min(9, bytes.length - k1); const limit2 = Math.ceil(1.22 * limit1); let buffer = 0n; for (let i = 0; i < limit1; ++i) { const byte = bytes[k1 + i]; if (byte < 0 || byte > 255) { throw new Error('Incorrect value in input bytes array.'); } buffer *= 256n; buffer += BigInt(byte); } let part = ''; for (let i = 0; i < limit2; ++i) { const rest = buffer % 94n; const value = Number(rest); const code = CODES[value]; part = code + part; buffer -= rest; buffer /= 94n; } base94 += part; } return base94; }; // Decodes Base94 string to bytes. // const decodeBase94 = (base94) => { const rest = base94.length % 11; if (rest === 1 || rest === 6) { throw new Error('Input data length is incorrect.'); } const length1 = base94.length; const length2 = Math.floor(0.82 * length1); const bytes = new Array(length2); for (let k1 = 0, k2 = 0; k1 < length1; k1 += 11, k2 += 9) { const limit1 = Math.min(11, length1 - k1); const limit2 = Math.floor(0.82 * limit1); let buffer = 0n; for (let i = 0; i < limit1; ++i) { const code = base94[k1 + i]; const value = VALUES[code]; if (value == null) { // null or undefined throw new Error('Incorrect base64 input character.'); } buffer *= 94n; buffer += BigInt(value); } for (let i = limit2 - 1; i > -1; --i) { const rest = buffer % 256n; const byte = Number(rest); bytes[k2 + i] = byte; buffer -= rest; buffer /= 256n; } } return bytes; }; // Usage example: const inputBytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; const base94 = encodeBase94(inputBytes); const outputBytes = decodeBase94(base94); console.log('Base94: ', base94); // AJ|iQ0U{Nl#/r;. console.log('Bytes: ', outputBytes); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] // Note: the solution bases on https://dirask.com/snippets/JavaScript-Base94-proposal-jPlJPj
Reset