为什么此实现有不同的结果?

时间:2019-08-30 10:10:51

标签: javascript c# hash bit-manipulation

嗨,我需要根据c#ts/js中的相同文本生成一些哈希/校验和 我在这里找到了一些关于stackoverflow的解决方案,但是有一些问题

所以我的js

private getStableHash(s, hashlength) {
let hash = 0;
const bytes = this.string2Bin(s); 
for (let i = 0; i < bytes.length; i++) {
    hash += bytes[i];
    hash += (hash << 10);
    hash ^= (hash >> 6);
}
// final avalanche
hash += (hash << 3);
console.log(hash);
hash ^= (hash >> 11);
console.log(hash);
hash += (hash << 10);
console.log(hash);
return Math.round(hash % hashlength);
}

 private string2Bin(str) {
 const result = [];
 for (let i = 0; i < str.length; i++) {
  result.push(str.charCodeAt(i));
 }
 return result;
 }

和c#

 private int GetStableHash(string s, int hashlength)
    {
        int 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 << 10);

        return (int)(hash % hashlength);
    }

getStableHash('dbo.files.xxx.yyy.zzz/aaa/3',10000000) 在两种情况下都返回7414302,所以它是FINE

但是如果我更改了最后一行

  hash += (hash << 10);

  hash += (hash << 15);

在两种实现方式中

c#在此行中将474798750更改为-1986274658,并返回-6274658

js在此行中将474798750更改为2308692638,并返回8692638

那是为什么?我在这里想念什么? 问候!

1 个答案:

答案 0 :(得分:4)

C#中的

int单个32位整数。如果进行位移位,将第一位设置为1,则数字将变为负数。

JS中的

number是64位浮点数,具有52位整数精度。但是,按位运算符只能在数字的 32位带符号表示上完成。

因此,两者的移位<<是相同的,但是加法 +=在C#中仅适用于32位,而在JS中仅适用于52位。