javascript - json-safe base94 encoding and decoding

JavaScript
[Edit]
+
0
-
0

JavaScript - JSON-safe Base94 encoding and decoding

9600
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
// ⚠️ 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/103oLj // 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 (from 0 to 255) to indexes of base94 codes (from 0 to 93). // const encodeBase94$1 = (bytes) => { const length1 = bytes.length; const length2 = Math.ceil(1.22 * length1); const base94 = new Array(length2); for (let k1 = 0, k2 = 0; k1 < length1; k1 += 9, k2 += 11) { const limit1 = Math.min(9, length1 - 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); } for (let i = limit2 - 1; i > -1; --i) { const rest = buffer % 94n; base94[k2 + i] = Number(rest); buffer -= rest; buffer /= 94n; } } return base94; }; // Decodes indexes of base94 codes (from 0 to 93) to bytes (from 0 to 255). // const decodeBase94$1 = (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]; if (code < 0 || code > 94) { throw new Error('Incorrect value in input base94 array.'); } buffer *= 94n; buffer += BigInt(code); } for (let i = limit2 - 1; i > -1; --i) { const rest = buffer % 256n; bytes[k2 + i] = Number(rest); buffer -= rest; buffer /= 256n; } } return bytes; }; // Encodes bytes (from 0 to 255) to JSON-safe base94 codes. // const encodeBase94$2 = (bytes) => { const values = encodeBase94$1(bytes); let base94 = ''; for (let i = 0; i < values.length; ++i) { const value = values[i]; base94 += CODES[value]; } return base94; }; // Decodes JSON-safe base94 codes to bytes (from 0 to 255). // const decodeBase94$2 = (base94) => { const values = new Array(base94.length); for (let i = 0; i < base94.length; ++i) { const code = base94[i]; const value = VALUES[code]; if (value == null) { // null or undefined throw new Error('Incorrect value in input base94 array.'); } values[i] = value; } return decodeBase94$1(values); }; // Usage example: const inputBytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; const base94 = encodeBase94$2(inputBytes); const outputBytes = decodeBase94$2(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: to find more optimal solution goto https://dirask.com/snippets/JavaScript-JSON-Base94-encoding-and-decoding-DNO7rp
Reset
[Edit]
+
0
-
0

JavaScript - JSON-safe Base94 encoding and decoding

9600
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