【问题标题】:Python: XOR hex strings [duplicate]Python:XOR 十六进制字符串 [重复]
【发布时间】:2013-01-09 16:16:26
【问题描述】:

可能重复:
bitwise XOR of hex numbers in python

我正在尝试在 Python 中对两个十六进制字符串进行异或运算,但我真的不知道从哪里开始。

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

a = "32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb"
b = "32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f90"

我应该使用这个吗?

  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)

【问题讨论】:

  • 您阅读过chrord 的文档吗?
  • a[:len(b)] 切片是多余的; zip() 无论如何都会将结果限制为最短的输入。
  • 附带说明,zip(a[:len(b)], b)zip(a,b) 相同,因为 zip 在两个可迭代对象中较短的那个结束时停止迭代。
  • @MartijnPieters -- 你赢了 7 秒 ... :) (try: Learn_Dvorak(); except RuntimeError: Lose_to_Martijn_again())
  • 阅读这个问题的答案stackoverflow.com/a/11119660/284795

标签: python cryptography hex ascii xor


【解决方案1】:

你在这里遗漏了一些东西。

首先,您不会想要异或 那些 字符串。你有编码形式的字符串,因此,你需要先.decode()它们:

binary_a = a.decode("hex")
binary_b = b.decode("hex")

然后,如前所述,一旦两个序列之一用完,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")

最后使用.encode(),我们将二进制字符串重新转换为打印良好的形式。

【讨论】:

  • 这不适用于 Python 3,其中 str 对象没有 decode 方法(并且 "hex" 无论如何都不是可识别的编码)。
  • 如果字符串中的数据是十六进制的数字,那么使用 ord 不会给你你需要的东西,ord("f") != 15,就像 glyphobet 说的那样使用int("f")
  • @F.C.这就是为什么你先做decode() ;)
  • @Blckknght Python 3 未在标签中指定,因此可以安全地假设它不需要。如果您已经知道它不起作用,为什么不指出在 Python 3 上使用的正确函数?
  • 我不确定是否有一种简单的方法可以在 Python 3 中将十六进制字符串逐字节解码为字节字符串。我在简短的检查中没有找到,如果您想对值进行数学运算(如 XOR),我认为@glyphobet 转换为整数而不是字节字符串的解决方案通常更好。
【解决方案2】:

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

>>> int('f', 16)
15 
>>> int('10', 16)
16

这样做:

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

【讨论】:

  • 这是一个很好的解决方案,因为它同时适用于所有十六进制字符(给出一个整数),而不是逐个字符或逐个字节。长十六进制字符串最终会创建非常大的整数(在 Python 2 中将使用 long 类型),但这对于使用它们的代码来说可能是不可见的。您可以通过使用字符串格式而不是 hex 内置函数来避免需要切掉 0x 位:"{:x}".format(16045690984833335023) 返回 'deadbeefdeadbeef'
  • 好点!我已更新代码以使用 {:x}.format() 而不是 hex()。谢谢。
  • @Blckknght 不错。我只是想知道 '{:x}.format()' 是如何工作的。谢谢。
猜你喜欢
  • 2016-12-27
  • 1970-01-01
  • 2012-09-25
  • 2011-05-15
  • 2015-03-09
  • 1970-01-01
  • 2010-10-04
  • 2014-03-07
相关资源
最近更新 更多