有人可以解释 Python 3 中的 XOR(用于校验和)吗

Can someone please explain XOR (for checksum) in Python 3

我正在为 foo.bar 做一个练习,基本思想是获取一个整数列表并对它做一些事情来导出该列表的特定子集,然后进行 XOR(用于校验和)这些值通过这个:

result = 0^1^2^3^4^6

等于 2

另一个例子:

result2 = 17^18^19^20^21^22^23^25^26^29

等于 14

我不太确定这里发生了什么以及这些值 (2, 14) 是如何得出的。

问题的实际描述来自 Foo.Bar

> 待办事项排队

你几乎已经准备好采取行动摧毁 LAMBCHOP 末日装置,但保护 LAMBCHOP 底层系统的安全检查站将成为一个问题。您能够在不触发任何警报的情况下取下一个,这太棒了!除了作为指挥官 Lambda 的助手,您了解到检查站即将进入自动审查,这意味着您的破坏行为将被发现并被揭穿 - 除非您可以欺骗自动审查系统。

要欺骗系统,您需要编写一个程序来 return 与警卫检查完所有工作人员后所拥有的安全校验和相同。幸运的是,Lambda 指挥官对效率的追求不允许排上几个小时的队,所以检查站的守卫们想出了加快通过率的方法。警卫没有检查每个通过的工人,而是检查了排队的每个人,同时记下他们的安全 ID,然后让队伍重新填满。一旦他们完成了,他们就会再次越过生产线,这次离开最后一个工人。他们继续这样做,每次都让一名工人离开生产线,但记录他们检查的那些人的安全 ID,直到他们跳过整条生产线,此时他们将他们记下的所有工人的 ID 异或到校验和中,并且然后起飞去吃午饭。幸运的是,工人的秩序性使他们总是按数字顺序排列,没有任何间隙。

例如,如果第一个工作人员的 ID 为 0,而安全检查点队列中有三个工作人员,则流程将如下所示:

0 1 2 /

3 4 / 5

6 / 7 8

守卫的 XOR (^) 校验和为 0^1^2^3^4^6 == 2。

同样,如果第一个工人的 ID 为 17 并且检查点有四个工人,则流程如下所示:

17 18 19 20 /

21 22 23 / 24

25 26 / 27 28

29 / 30 31 32

产生校验和 17^18^19^20^21^22^23^25^26^29 == 14.

所有工人 ID(包括第一个工人)都在 0 到 2000000000 之间(含),并且检查点行将始终至少有 1 个工人长。

根据这些信息,编写一个函数 answer(start, length),通过输出警卫通常在午餐前提交的相同校验和来覆盖丢失的安全检查点。在自动检查发生之前,您只有足够的时间找出要检查的第一个工人的 ID(开始)和行的长度(长度),因此您的程序必须仅使用这两个值生成正确的校验和。

测试用例

输入:

(int) start = 0

(int) length = 3

输出:

(int) 2

输入:

(int) start = 17

(int) length = 4

输出:

(int) 14

让我们看一下第一个示例中的值。请记住,这些都是按位运算符的二进制值。请注意,您发布的实际结果是 2,而不是 6:在 Python 解释器上检查它。

XOR 是给定输入的奇偶校验运算符:如果 1 的位数是偶数,则 XOR returns 0;如果是奇数,异或 returns 1. 让我们看看每个二进制列中有多少个 1 位:

0000
0001
0010
0011
0100
0110
----
0232 -- decimal count
0010 -- 1 for odd, 0 for even

...这是十进制数 2。

如果您对较大数字的较长序列执行相同的操作,则 XOR 的奇偶校验结果为 1110,即十进制的 14。


请注意,这将检测几个 类 简单错误,但它的主要弱点是无法检测两个项目的顺序是否颠倒。例如,[1, 2, 3] 和 [2, 1, 3] 将具有相同的校验和。有一个简单的升级调用 "cyclic redundancy check" (CRC) 执行 XOR,但为每个输入将输入旋转一个位置。第一项旋转 1 位,第二项旋转 2 位,依此类推

你想看看按位运算,这似乎是一篇关于它的文章:https://www.programiz.com/c-programming/bitwise-operators

按位运算背后的基本思想是,每个数字都以 2 为基数表示,即计算机内部的二进制格式。二元运算符使用此数字表示进行计算。

如果你应用一个运算(比如 xor ^,和 & or or |)那么你使用这个表示。

一个二进制数是这样表示的,可以转换成十进制表示(反之亦然): 0b1101 = 1 + 4 + 8 = 13

其中每一位代表 2 的幂。

当对两个数字进行异或时,比如 0b11000b1010,您正在创建一个新数字,只是设置了那些在两个参数中不相同的位

0b1100 ^ 0b1010 = 0b0110

根据您的具体示例:0^1^2^3^4^6 == 2

0^1 = 0b0000^0b0001 = 1
1^2 = 0b0010^0b0001 = 3
3^3 = 0b0011^0b0011 = 0
0^4 = 0b0000^0b0100 = 4
4^6 = 0b0100^0b0110 = 2