Skip to content

Instantly share code, notes, and snippets.

@TransparentLC
Created May 7, 2021 10:16
Show Gist options
  • Save TransparentLC/dbd3b72dc0cdbe10539d4a58dbdeb38a to your computer and use it in GitHub Desktop.
Save TransparentLC/dbd3b72dc0cdbe10539d4a58dbdeb38a to your computer and use it in GitHub Desktop.
Base85 编码和解码
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~';
const charsetReverse = charset
.split('')
.reduce((acc, cur, idx) => {
acc[cur] = idx;
return acc;
}, {});
/**
* @param {Uint8Array} data
* @returns {String}
*/
const base85Encode = data => {
const paddingLength = 4 - (data.length % 4 || 4);
const paddedData = new Uint8Array(data.length + paddingLength);
paddedData.set(data);
let result = '';
for (let i = 0; i < paddedData.length; i += 4) {
let group4 = 0;
for (let j = 0; j < 4; j++) {
group4 |= paddedData[i + j] << ((3 - j) << 3);
group4 >>>= 0;
}
let part85 = '';
for (let j = 0; j < 5; j++) {
let k = group4 % 85;
group4 = (group4 - k) / 85;
part85 = charset[k] + part85;
}
result += part85;
}
return result.substr(0, result.length - paddingLength);
};
/**
* @param {String} data
* @returns {Uint8Array}
*/
const base85Decode = data => {
const paddingLength = 5 - (data.length % 5 || 5);
data += '~'.repeat(paddingLength);
const result = new Uint8Array(data.length / 5 * 4 - paddingLength);
for (let i = 0, j = 0; i < data.length; i += 5, j += 4) {
let group5 = 0;
let base = 52200625; // 85 ** 4
for (let k = 0; k < 5; k++) {
group5 += base * charsetReverse[data[i + k]];
base /= 85;
}
for (let k = 0; k < 4; k++) {
result[j + k] = group5 >> ((3 - k) << 3);
}
}
return result;
};
for (let i = 0; i < 256; i++) {
const a = new Uint8Array(Math.random() * 262144);
for (let j = 0; j < a.length; j++) {
a[j] = Math.random() * 256;
}
const b = base85Decode(base85Encode(a));
if (a.length !== b.length) throw new Error('test failed');
for (let j = 0; j < a.length; j++) {
if (a[j] !== b[j]) throw new Error('test failed');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment