我有很多情况需要在C#中访问一个体面的哈希算法,从覆盖GetHashCode到对数据执行快速比较/查找.
我发现FNV哈希是一个非常简单/好/快的哈希算法.但是,我从未见过一个C#实现的好例子.
FNV-1a哈希算法的核心如下:
hash = OFFSET_BASIS
foreach (object value in object)
{
hash = hash ^ value.GetHashCode()
hash = hash * FNV_PRIME
}
Run Code Online (Sandbox Code Playgroud)
所以,当我覆盖GetHashCode一个类时,我最终做了类似的事情:
public static class FNVConstants
{
public static readonly int OffsetBasis = unchecked((int)2166136261);
public static readonly int Prime = 16777619;
}
public override int GetHashCode()
{
int hash = Constants.FNVConstants.OffsetBasis;
hash = (hash ^ EntityId.GetHashCode()) * Constants.FNVConstants.Prime;
hash = (hash ^ FromDate.GetHashCode()) * Constants.FNVConstants.Prime;
hash = (hash ^ ToDate.GetHashCode()) * Constants.FNVConstants.Prime;
return hash; …Run Code Online (Sandbox Code Playgroud) 我的iPhone项目中有一个HTTP连接器,查询必须使用Fowler-Noll-Vo(FNV)哈希从用户名中设置参数集.
我这时有一个Java实现,这是代码:
long fnv_prime = 0x811C9DC5;
long hash = 0;
for(int i = 0; i < str.length(); i++)
{
hash *= fnv_prime;
hash ^= str.charAt(i);
}
Run Code Online (Sandbox Code Playgroud)
现在在iPhone方面,我这样做了:
int64_t fnv_prime = 0x811C9DC5;
int64_T hash = 0;
for (int i=0; i < [myString length]; i++)
{
hash *= fnv_prime;
hash ^= [myString characterAtIndex:i];
}
Run Code Online (Sandbox Code Playgroud)
这个脚本没有给我与Java一样的结果.
在第一个循环中,我得到了这个:
hash = 0
hash = 100(首字母是"d")
hash = 1865261300(对于hash = 100和fnv_prime = -2128831035,如Java)
有人看到我失踪的东西吗?
在此先感谢您的帮助 !
我已经看到 Fowler-Noll-Vo (FNV) 被推荐为用于我们实现一致哈希系统的快速哈希算法的不错选择。
不过,似乎无法为它找到一个好的 Java 源代码。
我正在尝试3种不同的FNV1A_64哈希实现.
1)Maatkit
SELECT FNV1A_64('1')
Run Code Online (Sandbox Code Playgroud)
结果:-5808609649712063748
2)pyhash
import pyhash
hasher = pyhash.fnv1a_64()
print hasher('1')
Run Code Online (Sandbox Code Playgroud)
结果:53876069782339L
3)fnv
./fnv1a64 -s 1
Run Code Online (Sandbox Code Playgroud)
结果:0xaf63ac4c86019afc(12638134423997487000十进制)
为什么所有结果都不同?