我有以下代码:
public void AddHash( int val )
{
m_Hash ^= (val & 0x3FFFFFF);
m_Hash ^= (val >> 26) & 0x3F;
}
我非常想知道它的作用,但我会很高兴知道如何建立一个bool HasHash( int val )
来告诉我m_Hash是否有这个数字......
这样的事情?
public bool HasHash( int val )
{
return (m_Hash & val) == 0;
}
答案 0 :(得分:3)
代码的作用
它使用val
的最后26位,并使用XOR将其与m_Hash
结合使用。之后,它将它与val
的前6位组合在一起。因此,32位长度的整数将减少到26位。根据{{3}},这是不可逆。
HasHash功能
即使您只调用HasHash
一次,也无法创建AddHash
函数,因为val
中的多个输入值将导致相同m_hash
价值。
答案 1 :(得分:3)
编辑以解决@schnaader发现的错误:它的作用是什么?此代码可能 希望 向左(顺时针)向左旋转val
6位并形成补码和(编辑:不是产品,如我之前说过) - 旋转值的xor - 和m_Hash
的当前值,以产生新的m_Hash
。新的m_Hash
将在下次调用AddHash( )
时使用。
但是,编写的代码有一个错误:它只向左旋转val
的高位6位,留下val
的低位26位。然后代码将三个值组合在一起:
val
的新低位(旧高位)6位; val
;和m_Hash
将结果保留在m_Hash
中。
它是如何做到的?您可以将其映射并模拟它:
val & 0x3FFFFFF
表示提取val
的低位26位。 xor
这些26位,当前值为m_Hash
现在向右移动val
,使低位26位从低位端下降,留下曾经是低位val
的高位6位 - 订购val
的6位。
0x3f
进行掩码,仅提取那些低位6位(如果某些无关位被移位到val
的高位部分)。xor
那些低位6位,当前值为m_Hash
,以提供新的m_Hash
。您知道旋转和异或是计算哈希值时的常见操作。
编辑: @schnaader指出了原始代码中的错误:代码忘记了旋转的另一条腿:将低位26位左移6位。要解决这个问题,代码应该是这样的:
public void AddHash( int val )
{
m_Hash ^= ((val & 0x3FFFFFF) << 6);
m_Hash ^= (val >> 26) & 0x3F;
}
至于你的HasHash( )
功能:你应该知道说
return (m_Hash & val) == 0;
将在许多条件下返回TRUE,包括您可能不想要的一些条件。例如,如果m_Hash == 0xC0
和val == 0x03
,则函数将返回TRUE。