pseudohash
Version:
Short, reversable, alphanumeric pseudohash with hard-to-guess sequence.
108 lines (92 loc) • 2.71 kB
JavaScript
// Generated by CoffeeScript 2.0.0-beta2
/*
*
* Javascript port of Crypt::Pseudo
* https://github.com/CliffS/crypt-pseudo
*
* Originally ported from http://blog.kevburnsjr.com/php-unique-hash
* (Now defunct).
*
*/
(function() {
var BigInt, PseudoHash, bigint, goldenPrimes, invert, power;
BigInt = require('BigInt');
/*
goldenPrimes =
1: '1'
41: '59'
2377: '1677'
147299: '187507'
9132313: '5952585'
566201239: '643566407'
35104476161: '22071637057'
2176477521929: '294289236153'
134941606358731: '88879354792675'
8366379594239857: '7275288500431249'
518715534842869223: '280042546585394647'
*/
goldenPrimes = ['1', '41', '2377', '147299', '9132313', '566201239', '35104476161', '2176477521929', '134941606358731', '8366379594239857', '518715534842869223'];
bigint = function(v, base = 10) {
return BigInt.str2bigInt(v.toString(), base);
};
power = function(big, i) {
var j, p, ref;
p = bigint(1);
if (i > 0) {
for (j = 1, ref = i; 1 <= ref ? j <= ref : j >= ref; 1 <= ref ? j++ : j--) {
p = BigInt.mult(big, p);
}
}
return p;
};
invert = function(s) {
return s.replace(/\w/g, function(c) {
if (c.match('[a-z]')) {
return c.toUpperCase();
} else {
return c.toLowerCase();
}
});
};
PseudoHash = class PseudoHash {
constructor(bits = 62) {
var i, k;
if (!(bits === 36 || bits === 62)) {
throw 'Bits must be 62 or 36';
}
this.bits = bits;
bits = bigint(this.bits);
this.mmi = (function() {
var j, len1, results;
results = [];
for (i = j = 0, len1 = goldenPrimes.length; j < len1; i = ++j) {
k = goldenPrimes[i];
results.push(BigInt.inverseMod(bigint(k), power(bits, i)));
}
return results;
})();
}
hash(num, len = 5) {
var ceil, dec, hash, prime;
ceil = power(bigint(this.bits), len);
prime = goldenPrimes[len];
dec = BigInt.multMod(bigint(prime), bigint(num), ceil);
hash = BigInt.bigInt2str(dec, this.bits);
while (hash.length < len) {
hash = `0${hash}`;
}
return invert(hash);
}
unhash(hash) {
var ceil, dec, len, mmi, num;
len = hash.length;
hash = invert(hash);
ceil = power(bigint(this.bits), len);
mmi = this.mmi[len];
dec = bigint(hash, this.bits);
num = BigInt.multMod(mmi, dec, ceil);
return Number.parseInt(BigInt.bigInt2str(num, 10));
}
};
module.exports = PseudoHash;
}).call(this);