Благодаря превосходному ответу Марка я решил свою проблему с помощью следующего кода (CodePen Demo):
// Base 47 characters
var chars = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J',
'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'm', 'n', 'p', 'q', 'r', 't',
'u', 'v', 'w', 'x', 'y', 'z', '2', '3', '4',
'6', '7'
];
function encode(value) {
// Get toggle values and convert binary to decimal
var toggles = value.slice(0, value.length - 2); // string
var decimal = parseInt(toggles, 2); // number (0..1023)
// Get two-digit select value
var select = parseInt(value.slice(value.length - 2)); // number (0..99)
// Combine toggle and select values to a single integer
var possibility = (decimal * 100) + select; // number (0..103499)
var output = '';
// Get base47 value by successively dividing by 47,
// taking the remainder as a digit, and using the quotient
// for the next division
for(var i = 0; i < 3; i++) {
var quotient = Math.floor(possibility/47);
var remainder = possibility - (quotient * 47);
possibility = quotient;
output += chars[remainder];
}
return output;
} // encode(value)
function decode(value) {
var possibility = 0;
// Loop through base47 string, beginning from the end
// Recombine the base 47 digits by successively multiplying by 47
for(var i = value.length - 1; i >= 0; i--) {
var item = value[i];
var remainder = chars.indexOf(value[i]);
possibility = (possibility * 47) + remainder;
}
// Convert number to string
possibility = possibility.toString();
// Fill numbers < 3 digits with leading zeros
while(possibility.length < 3) { possibility = '0' + possibility; }
// Get toggles and select values from string
var toggles = possibility.slice(0, possibility.length - 2);
var select = possibility.slice(possibility.length - 2);
// Convert toggles string to binary string and add leading zeros
var binary = parseInt(toggles, 10).toString(2);
while(binary.length < 10) { binary = '0' + binary; }
// Return binary toggle values, followed by the select values
return binary + select;
} // decode(value)
Если вы хотите, чтобы избежать неоднозначности, вы можете захотеть использовать [base32] (https: //en.wikipedia .org/wiki/Base32) вместо base64, которая предназначена для избежания неоднозначных символов. – Frxstrem