string - 在 python 中,如何执行按位异或或者两个字符串?

我想在python中做位异或或字,但是,python中不允许字符串xor ,那么怎么做?

时间:

你可以将字符转换为整数,并将这些字符指定为整数:


l = [ord(a) ^ ord(b) for a,b in zip(s1,s2)]

以下是一个更新的函数,如果你需要一个字符串作为异常的结果,请执行以下操作:


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

如果你想操作字节或字,那么你最好使用python类型的数组而不是字符串。 如果使用固定长度块,那么可以使用H或L格式操作字而不是字节,


>>> 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()
';x00x0fx1enXS2x0cx00tx10R'

下面是字符串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
';x00x0fx1enXS2x0cx00tx10R'
>>> decrypt = xorWord(encrypt,code)
>>> print decrypt
Hello, World!

请注意,这是一种非常弱的加密形式,观察给定一个空白字符串以编码时发生的情况:


>>> codebreak = xorWord(" ", code)
>>> print codebreak
SECRET

对于bytearrays,你可以直接使用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'GWBx00TAG')


def strxor (s0, s1):
 l = [ chr ( ord (a) ^ ord (b) ) for a,b in zip (s0, s1) ]
 return ''.join (l)

你的意思是:


s1 = '00000001'
s2 = '11111110'
int(s1,2) ^ int(s2,2)

如果字符串的长度不相等,则可以使用,


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)])])


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)])

下面说明XORing字符串与m,然后再次反转该进程:


>>> s='hello, world'
>>> m='markmarkmark'
>>> s=''.join(chr(ord(a)^ord(b)) for a,b in zip(s,m))
>>> s
'x05x04x1ex07x02MRx1cx02x13x1ex0f'
>>> s=''.join(chr(ord(a)^ord(b)) for a,b in zip(s,m))
>>> s
'hello, world'
>>>

我发现''.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)))

...