как сделать поразрядно эксклюзивный или двух строк в Python?

Я хотел бы выполнить поразрядное эксклюзивное или двух строк в Python, но xor строк не позволяются в Python. Как я могу сделать это?

45
задан Mark S. 16 March 2016 в 18:42
поделиться

5 ответов

Вы можете преобразовать символы в целые числа и вместо этого выполнить xor:

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

60
ответ дан 26 November 2019 в 20:53
поделиться

Вот ваша строка 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
12
ответ дан 26 November 2019 в 20:53
поделиться

Ниже проиллюстрирована операция XORing строки 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'
>>>
1
ответ дан 26 November 2019 в 20:53
поделиться

Если вы хотите оперировать байтами или словами, то вам лучше использовать тип массива 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'
26
ответ дан 26 November 2019 в 20:53
поделиться

Вы имеете в виду что-то вроде этого:

s1 = '00000001'
s2 = '11111110'
int(s1,2) ^ int(s2,2)
2
ответ дан 26 November 2019 в 20:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: