C 为什么在OR上使用XOR?

C 为什么在OR上使用XOR?,c,xor,C,Xor,该部分: uint64_t k1 = 0; uint64_t k2 = 0; switch(len & 15) { case 15: k2 ^= ((uint64_t)tail[14]) << 48; case 14: k2 ^= ((uint64_t)tail[13]) << 40; case 13: k2 ^= ((uint64_t)tail[12]) << 32; case 12: k2 ^= ((uint64_

该部分:

  uint64_t k1 = 0;
  uint64_t k2 = 0;

  switch(len & 15)
  {
  case 15: k2 ^= ((uint64_t)tail[14]) << 48;
  case 14: k2 ^= ((uint64_t)tail[13]) << 40;
  case 13: k2 ^= ((uint64_t)tail[12]) << 32;
  case 12: k2 ^= ((uint64_t)tail[11]) << 24;
  case 11: k2 ^= ((uint64_t)tail[10]) << 16;
  case 10: k2 ^= ((uint64_t)tail[ 9]) << 8;
  case  9: k2 ^= ((uint64_t)tail[ 8]) << 0;
uint64\u t k1=0;
uint64_t k2=0;
开关(透镜和15)
{

案例15:k2^=((uint64_t)尾[14])是的,在这种情况下,它们是完全等效的。此外,由于它们是等效的,编译器可以自己使用它们进行优化。当您编译时,您不能保证它实际上是或异或或异或。实际上,在更一般的层面上,您不能保证它是其中任何一个,只要编译器生成可观察行为相同的代码

使用xor的一个合理理由是,这是程序员首先想到的,或者代码最初是以一种重要的方式编写的,但后来被更改为一种无关紧要的版本。但是,由于在这种情况下它们是等价的,所以很难知道

为什么在OR上使用XOR

如果可以在限制性代码中使用
|
^
来获取和归档相同的功能,那么首选的功能应该反映更大的问题

^
保留熵

当代码试图形成一个散列时(
^
^
优于
^
翻转位,通常会导致1和0的公平分布。
偏向于生成1

许多哈希算法都会像使用一样“添加”
a
b
,也就是说
a^b
而不是
a | b
。因此在这个哈希算法上下文中,
^
传达了更好的算法意图



我经常遇到使用
|
的哈希代码,不幸的是会导致有偏差的结果,而
^
会很好地工作。在我看来,哈希代码中的
|
是一个可能有偏差的危险信号。

你从一个案例到下一个案例都没有找到错误。这看起来像是一种错误。@JohnBollinger我没有错过它。但是如果你看一下索引和移位级别,字节不会重叠,所以XOR不会在那里发挥它的魔力,只是作为一个OR来工作。@texasbruce虽然CPU是由一个时钟来调整的,所以门的速度对性能没有影响。也许它是在作者改变它之前被设计为重叠的。无论如何,
xor
感觉更像是“加密逻辑”如果你说作者应该使用
,我们不妨说作者应该使用
添加
,然后代码只是将可变字节数转换成整数。这已经用了或几个世纪了。我认为作者没有理由先考虑异或,除非他已经处理了很多问题XOR最近。@Settlekapanoglu可能是这样的,因为它是正统的,所以它引起了人们的注意。我当然不会忽视这种可能性,只是想知道我是否在性能或行为方面遗漏了什么。显然,没有遗漏。@Settlekapanoglu改写了它。我仍然认为这只是因为
^
更容易理解打字更容易阅读。
|
有一堆看起来模棱两可的符号,你通常需要双手来打字(在某些键盘上找到它确实很痛苦)。此外,
^
让人们开始怀疑自己是否疯了,这总是一个额外的好处。在散列算法中,'or'和'xor'之间的核心区别在于'xor'操作保留了熵(“随机性”)在参数中,虽然“或”不是。不同均匀随机源的“xor”仍然是均匀随机的,但“或”不是,因为二进制结果将有多个1而不是0(“偏置”,如chux所述)。在这种情况下,不会因为使用或因为位位置不重叠而损失熵。这部分代码也与密码学无关;它只是一个将可变字节数转换为整数的代码。@Kapanoglu是的,我们都同意这段代码中的
^
没有熵。但问题是“为什么要在或上使用异或”。
^
更常用于
|
的哈希函数,否则会有熵损失。因此,使用
^
是更传统的哈希表示法,
|
会引起关注。即使你发现
也能更好地表达其意图“与
^
,哈希算法正好相反:
^
|
@chux更好地表达了它的意图,我理解你的意思,但我的问题是关于OR和XOR何时可互换,就像在示例中一样。你提到的熵案例意味着它们不可互换。