我在这里已经发布了几天相似的问题了,但似乎我没有问正确的事情,所以如果我因为XOR问题让你筋疲力尽,请原谅我:D。
到目前为止 - 我有两个十六进制字符串,我想对这些字符串进行异或,以便每个字节分别进行异或(即每对数字分别进行异或)。我想在python中这样做,我希望能够拥有不同长度的字符串。我将手动做一个例子来说明我的观点(我使用了代码环境,因为它允许我放入我希望它们的空间):
Input:
s1 = "48656c6c6f"
s2 = "61736b"
Encoding in binary:
48 65 6c 6c 6f = 01001000 01100101 01101100 01101100 01101111
61 73 6b = 01100001 01110011 01101011
XORing the strings:
01001000 01100101 01101100 01101100 01101111
01100001 01110011 01101011
00001101 00011111 00000100
Converting the result to hex:
00001101 00011111 00000100 = 0d 1f 04
Output:
0d1f04
因此,总而言之,我希望能够输入两个不同或相等长度的十六进制字符串(这些字符串通常是以十六进制编码的ASCII字母),并获得它们的XOR,使每个字节分别进行异或。
答案 0 :(得分:12)
使用binascii.unhexlify()
将十六进制字符串转换为二进制数据,然后使用binascii.hexlify()
将其转换为十六进制:
>>> from binascii import unhexlify, hexlify
>>> s1 = "48656c6c6f"
>>> s2 = "61736b"
>>> hexlify(''.join(chr(ord(c1) ^ ord(c2)) for c1, c2 in zip(unhexlify(s1[-len(s2):]), unhexlify(s2))))
'0d1f04'
实际的XOR应用于解码数据的每个字节(使用ord()
和chr()
进出整数)。
请注意,与您的示例中一样,我将s1
截断为与s2
相同的长度(忽略s1
开头的字符)。您可以通过循环字节来使用较短的密钥s1
对s2
的所有进行编码:
>>> from itertools import cycle
>>> hexlify(''.join(chr(ord(c1) ^ ord(c2)) for c1, c2 in zip(unhexlify(s1), cycle(unhexlify(s2)))))
'2916070d1c'
你没有 使用unhexlify()
,但它比一次循环s1
和s2
2个字符并使用它要容易得多int(twocharacters, 16)
将其转换为XOR运算的整数值。
上面的Python 3版本稍微轻一点;使用bytes()
代替str.join()
,您可以放弃chr()
和ord()
调用,直接迭代整数:
>>> from binascii import unhexlify, hexlify
>>> s1 = "48656c6c6f"
>>> s2 = "61736b"
>>> hexlify(bytes(c1 ^ c2 for c1, c2 in zip(unhexlify(s1[-len(s2):]), unhexlify(s2))))
b'0d1f04'
>>> from itertools import cycle
>>> hexlify(bytes(c1 ^ c2 for c1, c2 in zip(unhexlify(s1), cycle(unhexlify(s2)))))
b'2916070d1c'
答案 1 :(得分:6)
我找到了一个非常简单的解决方案:
def xor_str(a,b):
result = int(a, 16) ^ int(b, 16) # convert to integers and xor them
return '{:x}'.format(result) # convert back to hexadecimal
它将xor字符串直到其中一个主题结束
答案 2 :(得分:1)
我不确定你究竟在寻找什么,但希望这对你有用。
>>> def getstr(encoded):
return "".join([chr(int(i+k, 16))for (i,k) in zip(encoded[0::2], encoded[1::2])])
>>> getstr(s1)
'Hello'
>>> getstr(s2)
'ask'
从两个普通字符串开始,您可以找到类似这样的结果:
>>> "".join(reversed(["%02X" % (ord(c1) ^ ord(c2)) for c1, c2 in zip(reversed(getstr(s1)), reversed(getstr(s2)))]))
'0D1F04'