我希望使用相同“种子”的两个客户端通过输入时间戳或长整数,并返回一个类似于使用random()的浮点数来生成相同的数字。
例如,带有函数:hasher(String seed,long input);
hasher("StackOverflow", 1000000010); //returns 0.57217329503213..
hasher("StackOverflow", 1000000010); //returns 0.57217329503213...
hasher("StackOverflowz", 1000000010); //returns 0.15689784654554...
hasher("StackOverflow", 97494849465); //returns 0.456944151561...
实际上,它不应该是安全的或私有的,而应足够随机。我认为我可以使用位操作,但是我绝不是哈希或位操作方面的专家。
我意识到种子在组合种子和输入方面几乎是多余的,但是我想知道在其中实现种子而不损害可靠性的最佳方法将有所帮助。
有任何想法吗?
谢谢。
最佳答案
我做了一个小的实现,但是要注意JavaScript与我的主要语言相去甚远。该代码需要使用CryptoJS来实现哈希功能。
function hasher(a, b) {
hash = fromHex(CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(a + b)));
// warning: only about 32 bit precision
hashAsDouble = intFromBytes(hash.slice(0, 4)) * (1.0 / 4294967296.0);
return hashAsDouble;
}
function fromHex(hex) {
a = [];
for (var i = 0; i < hex.length; i += 2) {
a.push("0x" + hex.substr(i, 2));
}
return a;
}
function intFromBytes(x) {
if (x.length != 4) {
return null;
}
var val = 0;
for (var i = 0; i < x.length; i++) {
val = val << 8;
val = val + (x[i] & 0xFF);
}
return toUint32(val);
}
function modulo(a, b) {
return a - Math.floor(a / b) * b;
}
function toUint32(x) {
return modulo(toInteger(x), Math.pow(2, 32));
}
function toInteger(x) {
x = Number(x);
return x < 0 ? Math.ceil(x) : Math.floor(x);
}