我有以下 C# 哈希函数(也可以在 SO 上找到!),我在覆盖几个不同平台的一堆应用程序中使用它:
public static int GetStableHash(string s, int hashlength)
{
uint hash = 0;
var bytes = System.Text.Encoding.ASCII.GetBytes(s);
foreach (byte b in bytes)
{
hash += b;
hash += (hash << 10);
hash ^= (hash >> 6);
}
// final avalanche
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return (int)(hash % hashlength);
}
我正在尝试将其移植到 Javascript,另一个应用程序将在其中生成匹配的哈希值。唯一的问题是 JS 没有 uint 类型,并且似乎在执行按位数学之前在内部将整数转换为浮点数。这导致此移植功能出现问题:
function getStableHash(s, hashlength)
{
var hash = 0;
var bytes = stringToBytes(s); // this function just grabs a byte array for the given input string
for (var i = 0; i < bytes.length; i++)
{
hash += bytes[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
// final avalanche
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return Math.round(hash % hashlength);
}
在上面的代码中,由于存在签名位,移位最终会导致问题,并且生成的哈希与 C# 版本的输出不匹配。从其他各种 SO 帖子中还不清楚(例如,请参阅使用大整数的位运算)解决此问题的最佳方法是什么。
在 C# 和 C++ 中已经有使用散列方法的代码在生产中,因此不能在其他地方更改散列方法以适应 Javascript 的缺点。
如何解决 JS 的内部类型转换?