побитовое XOR шестнадцатеричных чисел в питоне

как мы можем XOR шестнадцатеричные числа в Python, например. Я хочу сделать xor 'ABCD' до «12EF». ответ должен быть B922.

я использовал код ниже, но он возвращает значение мусора

def strxor(a, b):     # xor two strings of different lengths
 if len(a) > len(b):
    return "".join(["%s" % (ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
else:
    return "".join(["%s" % (ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])

key ='12ef'
m1='abcd'
print  strxor(key,m1)
 user204450305 февр. 2013 г., 20:47
Я просто хочу отметить, что этот код взят из Стэнфордского класса криптографии на Coursera. Оригинальный постер не осознавал этого, но его проблема была не в коде. Его проблема заключалась в том, что он не признавал, что переводчик давал ему неанглийский ASCII в ответ.
 jfs06 окт. 2014 г., 05:30
 alexis04 окт. 2014 г., 15:32
Что может "не по-английски ASCII" имею в виду? Там нет такой вещи.
 eumiro20 июн. 2012 г., 14:37
Просто намек наzip: он автоматически удаляет более длинный аргумент. В любом случае, @unwind прав с его коротким решением.

Ответы на вопрос(5)

Для повышения производительности приведем небольшой код для сравнения этих двух альтернатив:

#!/bin/python

def hexxorA(a, b):
    if len(a) > len(b):
        return "".join(["%x" % (int(x,16) ^ int(y,16)) for (x, y) in zip(a[:len(b)], b)])
    else:
        return "".join(["%x" % (int(x,16) ^ int(y,16)) for (x, y) in zip(a, b[:len(a)])])

def hexxorB(a, b):
    if len(a) > len(b):
        return '%x' % (int(a[:len(b)],16)^int(b,16))
    else:
        return '%x' % (int(a,16)^int(b[:len(a)],16))

def testA():
    strstr = hexxorA("b4affa21cbb744fa9d6e055a09b562b87205fe73cd502ee5b8677fcd17ad19fce0e0bba05b1315e03575fe2a783556063f07dcd0b9d15188cee8dd99660ee751", "5450ce618aae4547cadc4e42e7ed99438b2628ff15d47b20c5e968f086087d49ec04d6a1b175701a5e3f80c8831e6c627077f290c723f585af02e4c16122b7e2")
    if not int(strstr, 16) == int("e0ff3440411901bd57b24b18ee58fbfbf923d68cd88455c57d8e173d91a564b50ce46d01ea6665fa6b4a7ee2fb2b3a644f702e407ef2a40d61ea3958072c50b3", 16):
        raise KeyError
    return strstr

def testB():
    strstr = hexxorB("b4affa21cbb744fa9d6e055a09b562b87205fe73cd502ee5b8677fcd17ad19fce0e0bba05b1315e03575fe2a783556063f07dcd0b9d15188cee8dd99660ee751", "5450ce618aae4547cadc4e42e7ed,99438b2628ff15d47b20c5e968f086087d49ec04d6a1b175701a5e3f80c8831e6c627077f290c723f585af02e4c16122b7e2")
    if not int(strstr, 16) == int("e0ff3440411901bd57b24b18ee58fbfbf923d68cd88455c57d8e173d91a564b50ce46d01ea6665fa6b4a7ee2fb2b3a644f702e407ef2a40d61ea3958072c50b3", 16):
        raise KeyError
    return strstr

if __name__ == '__main__':
    import timeit
    print("Time-it 100k iterations :")
    print("\thexxorA: ", end='')
    print(timeit.timeit("testA()", setup="from __main__ import testA", number=100000), end='s\n')
    print("\thexxorB: ", end='')
    print(timeit.timeit("testB()", setup="from __main__ import testB", number=100000), end='s\n')

Вот результаты:

Time-it 100k iterations :
    hexxorA: 8.139988073991844s
    hexxorB: 0.240523161992314s

Похоже на'%x' % (int(a,16)^int(b,16)) быстрее, чем версия на молнии.

здесь лучшая функция

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)])])
 10 мар. 2014 г., 04:48
Похоже, точный код из одного из заданий в курсе Crypto 1 на Coursera. ;)

Вау. Вы действительно чрезмерно усложняете это на очень большом расстоянии. Пытаться:

>>> print hex(0x12ef ^ 0xabcd)
0xb922

Вы, кажется, игнорируете эти полезные факты, по крайней мере:

Python has native support for hexadecimal integer literals, with the 0x prefix. "Hexadecimal" is just a presentation detail; the arithmetic is done in binary, and then the result is printed as hex. There is no connection between the format of the inputs (the hexadecimal literals) and the output, there is no such thing as a "hexadecimal number" in a Python variable. The hex() function can be used to convert any number into a hexadecimal string for display.

Если у вас уже есть числа в виде строк, вы можете использоватьint() Функция для преобразования в числа, предоставляя ожидаемую базу (16 для шестнадцатеричных чисел):

>>> print int("12ef", 16)
4874

Таким образом, вы можете сделать два преобразования, выполнить XOR, а затем преобразовать обратно в гекс:

>>> print hex(int("12ef", 16) ^ int("abcd", 16))
0xb922
 20 июн. 2012 г., 14:36
Конечно, если @pratibha имеет только строковые литералы, то альтернативой являетсяhex(int('12ef', 16) ^ int('abcd', 16))
 20 июн. 2012 г., 14:44
@DaV Спасибо, исправлено.
 pratibha20 июн. 2012 г., 14:41
привет спасибо за ответ Однако я получил это работает, как показано ниже:
 20 июн. 2012 г., 14:40
@unwind, второе число должно быть 0xabcd, следовательно, ожидаемый ответ 0xB922.

Если две шестнадцатеричные строки имеют одинаковую длину и вы хотите выводить шестнадцатеричную строку, вы можете попробовать это.

def hexxor(a, b):    # xor two hex strings of the same length
    return "".join(["%x" % (int(x,16) ^ int(y,16)) for (x, y) in zip(a, b)])

Если бы строки были одинаковой длины, то я бы пошел на'%x' % () из встроенного xor (^).

Примеры -

>>>a = '290b6e3a'
>>>b = 'd6f491c5'
>>>'%x' % (int(a,16)^int(b,16))
'ffffffff'
>>>c = 'abcd'
>>>d = '12ef'
>>>'%x' % (int(a,16)^int(b,16))
'b922'

Если строки имеют разную длину, обрежьте более длинную строку до длины более короткой, используя срезlonger = longer[:len(shorter)]

Ваш ответ на вопрос