Python не может декодировать XOR-строку с ключом больше 127 - PullRequest
0 голосов
/ 25 ноября 2018

У меня проблема с декодированием байтов в строку в Python.Я хотел взломать однобайтовый xor-шифр, перебрав его.И я сделал.Ключ был 90 (декабрь).Проблема здесь в том, что я на самом деле мог XOR каждый байт с номером > 127, но тогда я всегда получал UnicodeError, когда я хотел его декодировать.Все они выглядели одинаково, только разные байты:

128. 'utf-8' codec can't decode byte 0x98 in position 0: invalid start byte

def main():
    d = base64.b64decode(base64string)
    for i in range(1, 255):
        try:
            output_bytes = b''.join([bytes([b ^ i]) for b in d])
            decoded = output_bytes.decode('utf-8')
        except UnicodeDecodeError as e:
            print(f'{i}. {e}')
            pass


if __name__ == '__main__':
    main()

Мне либо пришлось написать блок try/except, чтобы предотвратить сбой моей программы, либо пришлось изменитьrange(1, 255) до range(1, 127).

Это ожидаемое поведение?Если нет, то что я делаю не так, и если да, то почему?Разве я не смогу сделать xor, а затем decode() независимо от того, какой байт я использую?

1 Ответ

0 голосов
/ 25 ноября 2018

UTF-8 ожидает, что байты имеют определенный формат.Если у вас нет правильной последовательности байтов, она может сгенерировать UnicodeDecodeError.Если у вас нет правильного ключа, он может потерпеть неудачу.Это также предполагает, что исходное сообщение было закодировано в UTF-8 для начала.Использование try / исключением - это правильное действие, если сообщение не имеет правильного ключа.

Например, вот строка Unicode, закодированная в UTF-8 и зашифрованная, затем декодированная со всеми возможными байтами XORключи.Только несколько ключей успешно декодируют UTF-8:

#coding:utf8
def encode(msg,key):
    data = msg.encode('utf8')
    return bytes(b ^ key for b in data)

def decode(msg,key):
    data = bytes(b ^ key for b in msg)
    try:
        return data.decode('utf8')
    except UnicodeDecodeError:
        return None

msg = "Hello, 马克!"
enc = encode(msg,0x90)
print(enc)

for i in range(256):
    dec = decode(enc,i)
    if dec is not None:
        print(f'{i:02x}: {dec}')

Вывод:

b'\xd8\xf5\xfc\xfc\xff\xbc\xb0y9<u\x15\x1b\xb1'
90: Hello, 马克!
91: Idmmn-!設䄊 
92: Jgnnm."뫮燉#
93: Kfool/#ꪯ憈"
96: Ncjji*&ﯪネ'
97: Obkkh+'₌&
98: @mddg$(ᡤ퍃)
99: Aleef%)ࠥ쌂(
9a: Boffe&*㣦+
9b: Cnggd'+⢧*
9c: Di``c ,奠鉇-
9d: Ehaab!-䤡舆,
9e: Fkbba".秢닅/
9f: Gjcc`#/榣ꊄ.
...