我想在python中执行两个字符串的按位异或,但是python中不允许字符串的异或。我该怎么做 ?
问问题
125058 次
12 回答
67
您可以将字符转换为整数,然后对它们进行异或:
l = [ord(a) ^ ord(b) for a,b in zip(s1,s2)]
这是一个更新的函数,以防您需要一个字符串作为 XOR 的结果:
def sxor(s1,s2):
# convert strings to a list of character pair tuples
# go through each tuple, converting them to ASCII code (ord)
# perform exclusive or on the ASCII code
# then convert the result back to ASCII (chr)
# merge the resulting array of characters as a string
return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2))
在线查看它:ideone
于 2010-04-10T08:18:55.883 回答
27
如果要对字节或单词进行操作,那么最好使用 Python 的数组类型而不是字符串。如果您使用的是固定长度的块,那么您可以使用 H 或 L 格式来操作单词而不是字节,但我在此示例中只使用了“B”:
>>> import array
>>> a1 = array.array('B', 'Hello, World!')
>>> a1
array('B', [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33])
>>> a2 = array.array('B', ('secret'*3))
>>> for i in range(len(a1)):
a1[i] ^= a2[i]
>>> a1.tostring()
';\x00\x0f\x1e\nXS2\x0c\x00\t\x10R'
于 2010-04-10T11:11:03.503 回答
17
对于字节数组,您可以直接使用 XOR:
>>> b1 = bytearray("test123")
>>> b2 = bytearray("321test")
>>> b = bytearray(len(b1))
>>> for i in range(len(b1)):
... b[i] = b1[i] ^ b2[i]
>>> b
bytearray(b'GWB\x00TAG')
于 2013-02-27T07:27:38.887 回答
15
这是您的字符串 XOR'er,大概用于某种温和的加密形式:
>>> src = "Hello, World!"
>>> code = "secret"
>>> xorWord = lambda ss,cc: ''.join(chr(ord(s)^ord(c)) for s,c in zip(ss,cc*100))
>>> encrypt = xorWord(src, code)
>>> encrypt
';\x00\x0f\x1e\nXS2\x0c\x00\t\x10R'
>>> decrypt = xorWord(encrypt,code)
>>> print decrypt
Hello, World!
请注意,这是一种极弱的加密形式。观察给定一个空白字符串进行编码时会发生什么:
>>> codebreak = xorWord(" ", code)
>>> print codebreak
SECRET
于 2010-04-10T09:26:32.450 回答
11
python3的一个衬里是:
def bytes_xor(a, b) :
return bytes(x ^ y for x, y in zip(a, b))
where a
,b
和返回的值bytes()
当然str()
是
再简单不过了,我喜欢 python3 :)
于 2015-02-12T15:57:23.933 回答
4
如果字符串的长度不相等,您可以使用它
def strxor(a, b): # xor two strings of different lengths
if len(a) > len(b):
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
else:
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])
于 2013-06-28T18:43:10.930 回答
4
def strxor (s0, s1):
l = [ chr ( ord (a) ^ ord (b) ) for a,b in zip (s0, s1) ]
return ''.join (l)
(基于 Mark Byers 的回答。)
于 2012-03-21T04:08:44.960 回答
2
你的意思是这样的:
s1 = '00000001'
s2 = '11111110'
int(s1,2) ^ int(s2,2)
于 2010-04-10T08:56:51.000 回答
1
下面说明了对字符串 s 与 m 进行异或运算,然后再次反转该过程:
>>> s='hello, world'
>>> m='markmarkmark'
>>> s=''.join(chr(ord(a)^ord(b)) for a,b in zip(s,m))
>>> s
'\x05\x04\x1e\x07\x02MR\x1c\x02\x13\x1e\x0f'
>>> s=''.join(chr(ord(a)^ord(b)) for a,b in zip(s,m))
>>> s
'hello, world'
>>>
于 2010-04-10T09:25:05.303 回答
1
def xor_strings(s1, s2):
max_len = max(len(s1), len(s2))
s1 += chr(0) * (max_len - len(s1))
s2 += chr(0) * (max_len - len(s2))
return ''.join([chr(ord(c1) ^ ord(c2)) for c1, c2 in zip(s1, s2)])
于 2012-01-13T17:48:44.110 回答
1
我发现 ''.join(chr(ord(a)^ord(b)) for a,b in zip(s,m)) 方法非常慢。相反,我一直在这样做:
fmt = '%dB' % len(source)
s = struct.unpack(fmt, source)
m = struct.unpack(fmt, xor_data)
final = struct.pack(fmt, *(a ^ b for a, b in izip(s, m)))
于 2013-10-22T08:14:27.737 回答
0
根据 William McBrine 的回答,这里有一个固定长度字符串的解决方案,它对我的用例来说要快 9%:
import itertools
import struct
def make_strxor(size):
def strxor(a, b, izip=itertools.izip, pack=struct.pack, unpack=struct.unpack, fmt='%dB' % size):
return pack(fmt, *(a ^ b for a, b in izip(unpack(fmt, a), unpack(fmt, b))))
return strxor
strxor_3 = make_strxor(3)
print repr(strxor_3('foo', 'bar'))
于 2016-10-29T13:42:49.937 回答