聚合哈希码最常用的方法也是建议从字节数组生成哈希码的方法。典型示例(这里使用Aggregate
只是为了得到stackoverflow的紧凑代码):
byte[] bytes;
var hashA = bytes.Aggregate(31, (i, b) => i * 31 + b);
var hashB = bytes.Aggregate(397, (i, b) => (i * 397) ^ b);
似乎与相对较小的正数相乘将主要影响只有少数元素的字节数组的最低有效位。加法和异或也是如此。
当您想通过哈希模算法进行负载平衡等时,这是完美的选择。然而,我目前有一个算法,它在事物最重要的方面是敏感的。 那么有没有类似的简单快速的散列方法,让小字节数组的最高有效位更“可变”?
最佳答案
首先,检查了几个真实的测试用例,它并没有看起来那么糟糕,其次,只需更改种子值即可轻松增强(参见 hashC
和 hashD
):
byte[] bytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int count = 1; count <= bytes.Length; count++)
{
var hashA = bytes.Take(count).Aggregate(31, (i, b) => i*31 + b);
var hashB = bytes.Take(count).Aggregate(397, (i, b) => (i*397) ^ b);
var hashC = bytes.Take(count).Aggregate(0xfedcbabc, (i, b) => (i*397) ^ b);
var hashD = bytes.Take(count).Aggregate(0xfedcbabc, (i, b) => (i*31) + b);
Console.WriteLine(hashA.ToString("X8") + " / " + hashB.ToString("X8") + " / " + hashC.ToString("X8") + " / " + hashD.ToString("X8"));
}
给出以下结果:
000003C1 / 000267A9 / 3C4D958C / DCBA9CC4
00007460 / 03BAC114 / 8450EA1D / BA98FBBD
000E17A2 / C89D6C06 / 317B0EFB / 98867BE5
01B4DCA1 / 1C20854D / BBD63B3C / 784900BE
34E6B783 / 9E6EB86D / 4B39DC08 / 90D71706
67F038E2 / B1B4010C / A8BA386D / 8A0BC9BF
9616E364 / 94259F9A / A8C9810F / B76D6E27
2CC58923 / BE5881D5 / C07D2444 / 364056C0
6BEB9B45 / 2F415759 / 82113D7C / 91CA8148
1187CD64 / 4854750C / B4BC5945 / A785A7C1
1F71DF26 / 2AF98396 / 4816700B / 492F5069
关于java - 任何快速简单的方法来散列小字节数组,以便最重要的位是最可变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31469148/