是否有任何标准的哈希函数/方法将任意9位整数映射到另一个(唯一的)9位整数,这样有点难以映射(不使用暴力)。
哈希不应该发生冲突,因此每个输出1 ≤ y < 10^9
都需要从1 ≤ x < 10^9
中的一个且只有一个输入值进行映射。
答案 0 :(得分:2)
您描述的问题实际上是格式保留加密旨在解决的问题。
NIST的一个标准是currently being worked out:用于分组密码的新的FFX加密模式。
它可能比你预期的更复杂。我在Javascript中找不到任何实现,但是其他语言中存在一些示例:here(Python)或here(C ++)。
答案 1 :(得分:1)
您需要一个只有大约30位的非冲突哈希函数。对于任何哈希函数来说,这都是一个很高的要求。实际上,你需要的不是伪随机函数,如散列,而是伪随机置换。
您可以使用加密功能,但显然需要保密密钥。此外,加密函数通常位作为输入和输出,10^9
不可能使用精确的位数。因此,如果您要使用这种选项,则可能必须使用格式保留加密。
您还可以使用组0..10 ^ 9-1中的任何其他PRP函数(在将值减1后),但如果攻击者发现您正在使用的参数,那么它变得非常简单恢复原状。一个例子是乘以一个相对素数的数乘以10 ^ 9-1,模10 ^ 9-1。
答案 2 :(得分:0)
This是我能想到的:
var used = {};
var hash = function (num) {
num = md5(num);
if (used[num] !== undefined) {
return used[num];
} else {
var newNum;
do {
newNum = Math.floor(Math.random() * 1000000000) + 1;
} while (contains(newNum))
used[num] = newNum;
return newNum;
}
};
var contains = function (num) {
for (var i in used) {
if (used[i] === num) {
return true;
}
}
return false;
};
var md5 = function (num) {
//method that return an md5 (or any other) hash
};
但是我应该注意,当你尝试散列很多不同的数字时会遇到问题,因为do..while
会生成随机数并将它们与已生成的数字进行比较。如果你已经生成了很多数字,它将越来越不可能找到剩下的数字。