我一直在读这篇文章,因为它是由Jon Skeet在这个答案上联系起来的.我试图真正理解哈希是如何工作的以及为什么乔恩喜欢他提供的算法.我还没有声称对此有答案,但我确实有一个关于基本System.String
实现的具体问题GetHashCode
.
考虑代码,重点是注释<<<<<==========
行:
public override unsafe int GetHashCode() { if (HashHelpers.s_UseRandomizedStringHashing) return string.InternalMarvin32HashString(this, this.Length, 0L); fixed (char* chPtr = this) { int num1 = 352654597; int num2 = num1; int* numPtr = (int*) chPtr; int length = this.Length; while (length > 2) { num1 = (num1 << 5) + num1 + (num1 >> 27) ^ *numPtr; num2 = (num2 << 5) + num2 + (num2 >> 27) ^ numPtr[1]; numPtr += 2; length -= 4; <<<<<========== } if (length > 0) num1 = (num1 << 5) + num1 + (num1 >> 27) ^ *numPtr; return num1 + num2 * 1566083941; } }
为什么他们只处理每四个字符?而且,如果你愿意,他们为什么要从右到左处理呢?
为什么他们只处理每四个字符?而且,如果你愿意,他们为什么要从右到左处理呢?
他们也没做.他们将字符作为整数值对处理(注意它们在while循环中使用*numPtr
和numPtr[1]
).两个Int32
值占用相同的空间,即4个字符,这就是为什么它们每次从长度中减去4的原因.
这是从前到后(按数组顺序)处理,但长度递减,因为它表示剩余要处理的字符串的长度.这意味着他们一次可以在"4个字符的块"中从左到右进行处理.