DockerERTFF/lib/core/base32.js

84 lines
1.9 KiB
JavaScript

const Variants = {
'RFC4648': {
alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
padding: true,
},
'RFC4648-HEX': {
alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV',
padding: true,
},
'CROCKFORD': {
alphabet: '0123456789ABCDEFGHJKMNPQRSTVWXYZ',
padding: false,
},
};
exports.encode = (input, opts = {}) => {
const Variant = Variants[opts.variant] || Variants['RFC4648'];
const alphabet = Variant.alphabet;
const padding = opts.padding != null ? opts.padding : Variant.padding;
const data = Buffer.from(input);
let bits = 0;
let value = 0;
let output = '';
for (let i = 0; i < data.length; i++) {
value = (value << 8) | data.readUInt8(i);
bits += 8;
while (bits >= 5) {
output += alphabet[(value >>> (bits - 5)) & 31];
bits -= 5;
}
}
if (bits > 0) {
output += alphabet[(value << (5 - bits)) & 31];
}
if (padding) {
while ((output.length % 8) !== 0) {
output += '=';
}
}
return output;
};
exports.decode = (input, opts = {}) => {
const Variant = Variants[opts.variant] || Variants['RFC4648'];
const alphabet = Variant.alphabet;
let bits = 0;
let value = 0;
if (opts.variant === 'CROCKFORD') {
input = input.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1');
} else {
input = input.replace(/=/g, '');
}
let index = 0;
let length = input.length;
let output = Buffer.alloc(Math.ceil(length * 5 / 8));
for (let i = 0; i < length; i++) {
let char = input[i];
let char_index = alphabet.indexOf(char);
if (char_index === -1) {
throw new Error('Invalid character: ' + char);
}
value = (value << 5) | char_index;
bits += 5;
if (bits >= 8) {
output.writeUInt8((value >>> (bits - 8)) & 255, index++);
bits -= 8;
}
}
return output;
};