/*
Base‑36 encoding/decoding in JavaScript
-------------------------------------------------
Base‑36 digits: 0–9, A–Z
Encoding:
- Convert string → bytes (UTF‑8)
- Convert bytes → BigInt (base‑256)
- Convert BigInt → base‑36 using built‑in toString(36)
Decoding:
- Convert base‑36 → BigInt
- Convert BigInt → bytes (base‑256)
- Convert bytes → original UTF‑8 string
JavaScript's BigInt makes this extremely clean and efficient.
*/
const BASE36_DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Encode any string into Base‑36
function encodeToBase36(text) {
// Convert string → UTF‑8 bytes
const bytes = new TextEncoder().encode(text);
// Convert bytes → BigInt (base‑256)
let n = 0n;
for (const b of bytes) {
n = n * 256n + BigInt(b);
}
// Convert BigInt → Base‑36
return n.toString(36).toUpperCase();
}
// Decode Base‑36 back into original string
function decodeFromBase36(encoded) {
encoded = encoded.toUpperCase();
// Convert Base‑36 → BigInt
let n = BigInt("0");
for (const c of encoded) {
const digit = BASE36_DIGITS.indexOf(c);
n = n * 36n + BigInt(digit);
}
// Convert BigInt → bytes (base‑256)
const bytes = [];
while (n > 0n) {
const byte = Number(n % 256n);
bytes.push(byte);
n = n / 256n;
}
bytes.reverse();
return new TextDecoder().decode(new Uint8Array(bytes));
}
// Usage
const text = "Hello Universe!";
const encoded = encodeToBase36(text);
const decoded = decodeFromBase36(encoded);
console.log("Original:", text);
console.log("Base-36 encoded:", encoded);
console.log("Decoded:", decoded);
/*
run:
Original: Hello Universe!
Base-36 encoded: LP4N024HJ1YVBVD84Y8TYQP
Decoded: Hello Universe!
*/