how to do bitwise exclusive or of two strings in p

2020-01-27 13:55发布

I would like to perform a bitwise exclusive or of two strings in python, but xor of strings are not allowed in python. How can I do it ?

12条回答
戒情不戒烟
2楼-- · 2020-01-27 14:37

You can convert the characters to integers and xor those instead:

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

Here's an updated function in case you need a string as a result of the 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))

See it working online: ideone

查看更多
Fickle 薄情
3楼-- · 2020-01-27 14:39

For bytearrays you can directly use 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')
查看更多
看我几分像从前
4楼-- · 2020-01-27 14:41
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)])
查看更多
一夜七次
5楼-- · 2020-01-27 14:44

I've found that the ''.join(chr(ord(a)^ord(b)) for a,b in zip(s,m)) method is pretty slow. Instead, I've been doing this:

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)))
查看更多
太酷不给撩
6楼-- · 2020-01-27 14:45
def strxor (s0, s1):
  l = [ chr ( ord (a) ^ ord (b) ) for a,b in zip (s0, s1) ]
  return ''.join (l)

(Based on Mark Byers answer.)

查看更多
倾城 Initia
7楼-- · 2020-01-27 14:45

If the strings are not even of equal length, you can use this

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)])])
查看更多
登录 后发表回答