Python:XOR十六进制字符串

Kok*_*ong 20 python hex ascii cryptography xor

可能重复:
python中十六进制数的按位异或

我试图在Python中XOR两个十六进制字符串,并不知道从哪里开始.

我有两个十六进制字符串:

a = "32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb"
b = "32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f90"
Run Code Online (Sandbox Code Playgroud)

我应该用这个吗?

  1. return "".join([chr((x) ^ (y)) for (x,y) in zip(a[:len(b)], b)])
  2. return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])

我不明白上面两个代码的区别.为什么chrord?我也见过人们使用int(hex,16).

pha*_*t0m 33

你在这里遗漏了几件事.

首先,您不希望对这些字符串进行异或.你有一个编码形式的字符串,因此,你.decode()首先需要它们:

binary_a = a.decode("hex")
binary_b = b.decode("hex")
Run Code Online (Sandbox Code Playgroud)

然后,如前所述,zip()只要两个序列中的一个用尽,该函数就会停止迭代.不需要切片.

你需要循环的第二个版本:首先,你想得到字符的ASCII值:ord()产生一个数字.这是必要的,因为^只适用于数字.

对数字进行异或后,然后将数字转换回字符chr:

def xor_strings(xs, ys):
    return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys))

xored = xor_strings(binary_a, binary_b).encode("hex")
Run Code Online (Sandbox Code Playgroud)

使用.encode()在最后,我们得到的二进制串回一个形式,即印刷精美.

  • 这在Python 3上不起作用,在Python 3上,str对象没有decode方法(无论如何,“ hex”都不是公认的编码)。 (2认同)
  • @Blckknght标签中没有指定Python 3,因此可以安全地假设它不需要.如果您已经知道它不起作用,为什么不指出在Python 3上使用的正确函数? (2认同)
  • 我不确定是否有一种简单的方法可以在Python 3中将十六进制字符串逐字节解码为字节字符串.我在简短的检查中没有找到一个,我认为@ glyphobet的转换解决方案如果你想对值进行数学运算(如XOR),那么整数而不是字节串通常会更好. (2认同)

gly*_*bet 18

int('', 16) 使用base 16将十六进制字符串转换为整数:

>>> int('f', 16)
15 
>>> int('10', 16)
16
Run Code Online (Sandbox Code Playgroud)

这样做:

result = int(a, 16) ^ int(b, 16) # convert to integers and xor them together
return '{:x}'.format(result)     # convert back to hexadecimal
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案,因为它可以同时处理所有十六进制字符(给出一个整数),而不是逐字符或逐字节.长十六进制字符串将最终创建非常大的整数(将在Python 2中使用`long`类型),但这可能对使用它们的代码不可见.你可以避免需要通过使用字符串格式来切掉"0x"位,而不是`hex` builtin:`"{:x}".format(16045690984833335023)`return`'deadbeefdeadbeef'` (3认同)