Python 如何对两个十六进制字符串进行异或运算,使每个字节分别进行异或运算?
我已经在这里发布了几天类似的问题,但似乎我问的不是正确的事情,所以请原谅,如果我已经用我的XOR问题让你筋疲力尽了:D 说到这里,我有两个十六进制字符串,我想对这些字符串进行异或运算,这样每个字节都是单独进行异或运算的(即,每对数字都是单独进行异或运算的)。我想在python中实现这一点,我想能够拥有不同长度的字符串。我将手动执行一个示例来说明我的观点(我使用了代码环境,因为它允许我将它们放在我想要的空间中): 因此,总而言之,我希望能够输入两个长度不同或相等的十六进制字符串(通常是用十六进制编码的ASCII字母),并获得它们的XOR,以便每个字节分别进行XOR。用于将十六进制字符串转换为二进制数据,然后使用XOR返回十六进制: 实际的异或应用于解码数据的每个字节(使用Python 如何对两个十六进制字符串进行异或运算,使每个字节分别进行异或运算?,python,string,hex,encode,xor,Python,String,Hex,Encode,Xor,我已经在这里发布了几天类似的问题,但似乎我问的不是正确的事情,所以请原谅,如果我已经用我的XOR问题让你筋疲力尽了:D 说到这里,我有两个十六进制字符串,我想对这些字符串进行异或运算,这样每个字节都是单独进行异或运算的(即,每对数字都是单独进行异或运算的)。我想在python中实现这一点,我想能够拥有不同长度的字符串。我将手动执行一个示例来说明我的观点(我使用了代码环境,因为它允许我将它们放在我想要的空间中): 因此,总而言之,我希望能够输入两个长度不同或相等的十六进制字符串(通常是用十六进制编
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'
您不必使用unexlify()
,但这比一次循环s1
和s2
两个字符并使用int(两个字符,16)
将其转换为用于异或操作的整数值要容易得多
上面的Python3版本稍微轻一点;使用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'
我不确定你到底在寻找什么,但希望这对你有用
>>> 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'
我找到了一个非常简单的解决方案:
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
它将对字符串进行异或运算,直到其中一个主题结束为什么不循环
s2
键并将其应用于s1
的所有字符?为什么只适用于最后3个?谢谢你的回答!我不明白的是,这一部分:对于c1,c2在zip中(unhexlify(s1),cycle(unhexlify(s2‘‘‘)’)),问题是,我是python新手,很容易被搞糊涂。我认为zip函数与数组有关,但我不知道这些函数在Python中是如何工作的。此外,我认为for循环只有一个计数器,但这里有两个-c1和c2,这也让我感到困惑。zip()
接受多个输入序列,并将它们的元素配对。因此,它给出了一个[(s1[0],s2[0]),(s1[1],s2[1]),…]的序列。
,每个元组都是从同一索引的每个输入序列中提取元素而形成的。@NorsulRonsul:因为在这种情况下zip()
有两个输入列表,每个输出元素都是一个具有两个值的元组。for
循环将它们解压为两个值(就像您可以在常规赋值中解压元组一样,foo,bar=('spam','egs'))
assignsfoo='spam'
和bar='eggs'
。我现在明白了,但我现在有另一个问题:D.我不明白你在第二部分做了什么。对所有s1进行编码意味着什么?循环字节意味着什么?@NorsulRonsul:不是只编码3个字符('llo'
的'Hello'
)和钥匙的3个字符(询问
),我们通过重复使用键对所有Hello
进行编码,当您到达终点时从起点重新开始;H
使用a
,e
使用s
,l
使用k
,然后再次循环到起点,使用a
对l
进行编码,使用s
对进行编码ertools.cycle()
方法让我们只用一个函数就可以实现在s2
上循环。当人们不使用内置格式时,它总是让我感到不舒服。返回格式(结果,'x')
。
>>> "".join(reversed(["%02X" % (ord(c1) ^ ord(c2)) for c1, c2 in zip(reversed(getstr(s1)), reversed(getstr(s2)))]))
'0D1F04'
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