java - 任何快速简单的方法来散列小字节数组,以便最重要的位是最可变的?

标签 java .net algorithm hash

聚合哈希码最常用的方法也是建议从字节数组生成哈希码的方法。典型示例(这里使用Aggregate只是为了得到stackoverflow的紧凑代码):

byte[] bytes;
var hashA = bytes.Aggregate(31, (i, b) => i * 31 + b);
var hashB = bytes.Aggregate(397, (i, b) => (i * 397) ^ b);

似乎与相对较小的正数相乘将主要影响只有少数元素的字节数组的最低有效位。加法和异或也是如此。

当您想通过哈希模算法进行负载平衡等时,这是完美的选择。然而,我目前有一个算法,它在事物最重要的方面是敏感的。 那么有没有类似的简单快速的散列方法,让小字节数组的最高有效位更“可变”?

最佳答案

首先,检查了几个真实的测试用例,它并没有看起来那么糟糕,其次,只需更改种子值即可轻松增强(参见 hashChashD):

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/

相关文章:

java - 计算颜色的差异

java - 如何对文本进行断字?

.net - 如何在 Maxscript 中使用点网字符串.Split

c# - 如何在多线程应用程序中正确卸载AppDomain?

java - 查找一个非常大的数是否可以被 7 整除的高效算法

algorithm - Mathematica 生成带锁定位的二进制数

java: Runtime.exec() Thread 和 errorOutput, readLine

java,tomcat : what is the meaning of the id attribute in the tag web-app in web. xml?

c# - 如何在不离开根组件的情况下处理大量 "dialogs"?

c++ - 基于区间的数据结构(类似于boost icl)