我正在寻找恒定时间算法可以将有序整数索引值更改为随机哈希索引。如果它是可逆的那就太好了。我需要哈希键对每个索引都是唯一的。我知道这可以通过在大文件中查找表来完成。 I.E.创建一个有序的所有整数集,然后随机地随机播放它们并以随机顺序写入文件。然后,您可以根据需要阅读它们。但这需要寻找一个大文件。我想知道是否有一种简单的方法可以使用伪随机生成器来根据需要创建序列?
Generating shuffled range using a PRNG rather than shuffling answer依据 erikkallen线性反馈移位寄存器看起来像是正确的东西。我只是试了一下,但它会产生重复和漏洞。
此致 大卫艾伦芬奇
答案 0 :(得分:4)
现在的问题是,如果你需要一个真正随机的映射,或者只是一个“弱”的排列。假设后者,如果在2的补码算术上使用无符号32位整数(比方说),则乘以任何奇数都是双射和可逆映射。当然,对于XOR也是如此,因此您可能尝试使用的简单模式就是例如。
unsigned int hash(int x) {
return (((x ^ 0xf7f7f7f7) * 0x8364abf7) ^ 0xf00bf00b) * 0xf81bc437;
}
数字中没有任何神奇之处。所以你可以改变它们,它们甚至可以随机化。唯一的事情是被乘数必须是奇数。你必须用rollaround计算(忽略溢出)。这可以倒置。要进行反演,您需要能够计算正确的互补被乘数A和B,之后反演为
unsigned int rhash(int h) {
return (((x * B) ^ 0xf00bf00b) * A) ^ 0xf7f7f7f7;
}
你可以用数学方法计算A和B,但更简单的方法就是运行循环并搜索它们(一旦离线,就是这样)。
该等式使用与乘法混合的XOR来使映射非线性化。
答案 1 :(得分:3)
您可以尝试构建合适的Feistel network。这些通常用于加密(例如DES),但至少有64位,因此您可能需要自己构建一个适合您的需求。它们可以通过施工来改变。
答案 2 :(得分:1)
假设您的目标是在整个范围内分散分组值,
看起来像是以某种预先定义的顺序对比特进行改组可能会起到作用
即给定8位ABCDEFGH,将它们排列为EGDBHCFA或某些此类模式。
代码只是一个简单的掩码,移位和添加序列。
答案 3 :(得分:0)
嗯......取决于你是否有很多数字,你可以使用普通的stl列表,并按“随机”标准订购
bool
nonsort(int i, int j)
{
return random() & 31 >16 ? true : false;
}
std::list<int> li;
// insert elements
li.sort(nonsort);
然后,您可以使用普通迭代器获取所有整数。请记住使用srand()随时间或任何其他伪随机值初始化随机。
答案 4 :(得分:0)
对于这组约束,确实没有解决方案。尝试将32位无符号散列为32位无符号,将为您提供冲突,除非您执行简单的操作,例如1对1映射。每个数字都是自己的哈希值。