Cryptography 汉明距离常数来自哪里

Cryptography 汉明距离常数来自哪里,cryptography,bit-manipulation,hamming-distance,Cryptography,Bit Manipulation,Hamming Distance,: 函数popcount(x,n){ 如果(n!==未定义){ x&=(1>1&0x5555 x=(x&0x33333333)+(x>>2&0x33333333) x=x+(x>>4)和0x0F0F x+=x>>8 x+=x>>16 返回x&0x7f } 是用于计算的。我想知道这些常量从何而来,以及这个方法是如何发现的。想知道是否有人知道描述它的资源。有掩码选择偶数的k位部分,k=1表示0x555555,k=2表示0x33333333,k=4表示0x0F0F 在二进制中,遮罩看起来像: 0x5

:

函数popcount(x,n){
如果(n!==未定义){
x&=(1>1&0x5555
x=(x&0x33333333)+(x>>2&0x33333333)
x=x+(x>>4)和0x0F0F
x+=x>>8
x+=x>>16
返回x&0x7f
}

是用于计算的。我想知道这些常量从何而来,以及这个方法是如何发现的。想知道是否有人知道描述它的资源。

有掩码选择偶数的k位部分,k=1表示0x555555,k=2表示0x33333333,k=4表示0x0F0F

在二进制中,遮罩看起来像:

0x55555555 = 01010101010101010101010101010101
0x33333333 = 00110011001100110011001100110011
0x0f0f0f0f = 00001111000011110000111100001111
它们也是0xFFFFFF/3、0xffffffff/5和0xffffffff/17的结果,但此算术细节在这种情况下可能没有用处

总的来说,这种计算汉明权重的方法具有树的形式,其中第一个相邻位被求和为2位数字,然后相邻的2位数字被求和为4位数字,依此类推

所有步骤都可以有以下形式:

x = (x & m[k]) + ((x >> k) & m[k])
其中,
m[k]
是选择偶数k位部分的掩码

但许多步骤都有捷径可供选择。例如,要对相邻位求和,只有4种情况需要考虑:

00 -> 00
01 -> 01
10 -> 01
11 -> 10
这可以通过提取两个位并求和来完成,但是
x-=x>>1&0x555555
也可以工作

00 -> 00 - 0 = 00
01 -> 01 - 0 = 01
10 -> 10 - 1 = 01
11 -> 11 - 1 = 10
也许这可以通过“聪明和洞察力”来发现,不管这些是什么

在步骤
x=(x+(x>>4))&0x0f0f
(为清晰起见,添加了额外的括号),使用了两个属性。前面步骤的结果是存储在4位中的4位字符串的汉明权重,因此它们最多为0100。这意味着可以将其中两个添加到位,而无需进行下一个更高的部分,因为它们的总和最多为1000,这仍然适用。因此,不要在总和之前屏蔽两次,在求和之后屏蔽一次就足够了,该屏蔽有效地将偶数的4位部分扩展为8位部分。这可以通过考虑每一步的最大值来发现

步骤
x+=x>>8
有类似的推理,但效果更好,即使在不需要求和后屏蔽,也会留下一些“杂散位”在底部的第二个字节和顶部的字节中,但这不会破坏下一步:16丢弃底部的第二个字节,最后用
x&0x7f
删除所有杂散位

00 -> 00 - 0 = 00
01 -> 01 - 0 = 01
10 -> 10 - 1 = 01
11 -> 11 - 1 = 10