我想从表示数字
的字符串生成一个新的唯一20位数字符串例如:
var uid = key.pseudoHash("00000000000000000000"), // "45021-78054-45021-16875"
uid = key.pseudoHash("00000000000000000001"), // "15751-40213-97315-65348"
..
uid = key.pseudoHash("99999999999999999999"); // "01197-95791-58880-58368"
如何使这个伪哈希函数不会发生碰撞而哪些可以反转?
答案 0 :(得分:0)
许多方法的一种方法是使用简单的substitution cipher:
// guaranteed random!
var key = [1, 3, 3, 1, 8, 3, 5, 7, 2, 9, 0, 2, 8, 2, 9, 7, 7, 8, 1, 7];
function test(str) {
str = str.split("");
for(var i = 0; i < str.length; i++) {
str[i] = (Number(str[i]) + key[i]) % 10
}
return str.join("");
}
console.log(test("00000000000000000000")); // 13318357290282977817
console.log(test("00000000000000000001")); // 13318357290282977818
console.log(test("99999999999999999999")); // 02207246189171866706
要获得更多随机性,您可以添加更多confusion and diffusion步骤。
这很容易被任何人逆转。对于安全算法,请查看加密。
答案 1 :(得分:0)
请不要执行此操作,因为它使用了JS的笨拙的“模数”运算符(我在C#中通过单元测试发现了一个错误):
var key = [1, 3, 3, 1, 8, 3, 5, 7, 2, 9, 0, 2, 8, 2, 9, 7, 7, 8, 1, 7];
function test(str) {
str = str.split("");
for(var i = 0; i < str.length; i++) {
str[i] = (Number(str[i]) + key[i]) % 10
}
return str.join("");
}
function untest(str) {
str = str.split("");
for(var i = 0; i < str.length; i++) {
str[i] = (Number(str[i]) - key[i]) % 10
}
return str.join("");
}
document.write(test("1000000001")); // 2331835720
document.write("<br></br>");
document.write(untest("2331835720")); // oh dear this doesn't round-trip: actually returns 100000000-9 and not 1000000001
document.write("<br></br>");
document.write( -9 % 10 );
document.write("<br></br>");
您可以通过将%10替换为模函数(按照下面的C#代码段)来避免这种情况:
static private int Mod(int x, int m)
{
return (x % m + m) % m;
}