Skip to content

Instantly share code, notes, and snippets.

@jackhftang
Last active September 6, 2016 13:29
Show Gist options
  • Save jackhftang/6545c3637820e489881317f0c7592a71 to your computer and use it in GitHub Desktop.
Save jackhftang/6545c3637820e489881317f0c7592a71 to your computer and use it in GitHub Desktop.
In general, encode integer into string, and then decode it back. The encoded sequence look completely random and suitable for shortener. This implements allow integer of range 0 to 62^6-1 = 56800235583 > 2^35
const digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const digitsReverse = (function(){
var arr = digits.split('');
var table = {};
for(var i=0; i<arr.length; i++) table[arr[i]] = i;
return table;
})();
const dim = 6;
const modulo = 62;
const shift = [26, 13, 47, 40, 11, 19];
const forward = [
[6, 16, 9, 25, 32, 6],
[16, 12, 9, 27, 13, 59],
[55, 37, 41, 48, 53, 55],
[31, 26, 30, 46, 44, 58],
[27, 61, 8, 4, 43, 25],
[35, 8, 35, 49, 19, 36]
];
const backward = [
[2, 12, 40, 19, 34, 30],
[31, 43, 6, 41, 51, 60],
[50, 16, 59, 50, 57, 60],
[5, 2, 19, 20, 47, 26],
[21, 40, 20, 21, 38, 21],
[28, 41, 52, 25, 28, 37]
];
function encode(id) {
// O(dim)
var arr = new Array(dim);
for (let i=0; i<dim; i++){
arr[i] = id % modulo;
id = Math.floor(id/modulo);
}
// O(dim^2)
var res = shift.concat();
for(let i=0; i<dim; i++){
for(let j=0; j<dim; j++){
res[i] += forward[i][j] * arr[j];
}
}
return res.map(i => digits[i%modulo]).join('');
}
function decode(hash) {
// assert( hash.length == dim )
// O(dim)
var arr = new Array(dim);
for(let i=0; i<dim; i++){
var c = hash[i];
arr[i] = digitsReverse[c] + modulo - shift[i];
}
// O(dim^2)
var ans = 0;
var base = 1;
for(let i=0; i<dim; i++){
var t = 0;
for(let j=0; j<dim; j++){
t += backward[i][j] * arr[j];
}
ans += (t%modulo) * base;
base *= modulo;
}
return ans;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment