简体   繁体   中英

Hex string convert to ASCII after XOR

I am new to Python & I am trying to learn how to XOR hex encoded ciphertexts against one another & then derive the ASCII value of this.

I have tried some of the functions as outlined in previous posts on this subject - such as bytearray.fromhex, binascii.unhexlify, decode("hex") and they have all generated different errors (obviously due to my lack of understanding). Some of these errors were due to my python version (python 3).

Let me give a simple example, say I have a hex encoded string ciphertext_1 ("4A17") and a hex endoded string ciphertext_2. I want to XOR these two strings and derive their ASCII value. The closest that I have come to a solution is with the following code:

result=hex(int(ciphertext_1, 16) ^ int(ciphertext_2, 16))
print(result)

This prints me a result of: 0xd07 (This is a hex string is my understanding??)

I then try to convert this to its ASCII value. At the moment, I am trying:

binascii.unhexliy(result)

However this gives me an error: "binascii.Error: Odd-length string" I have tried the different functions as outlined above, as well as trying to solve this specific error (strip function gives another error) - however I have been unsuccessful. I realise my knowledge and understanding of the subject are lacking, so i am hoping someone might be able to advise me?

Full example:

#!/usr/bin/env python
import binascii

ciphertext_1="4A17"
ciphertext_2="4710"

result=hex(int(ciphertext_1, 16) ^ int(ciphertext_2, 16))
print(result)
print(binascii.unhexliy(result))
from binascii import unhexlify

ciphertext_1 = "4A17"
ciphertext_2 = "4710"
xored = (int(ciphertext_1, 16) ^ int(ciphertext_2, 16))
# We format this integer: hex, no leading 0x, uppercase
string = format(xored, 'X')
# We pad it with an initial 0 if the length of the string is odd
if len(string) % 2:
    string = '0' + string
# unexlify returns a bytes object, we decode it to obtain a string
print(unhexlify(string).decode())
#
# Not much appears, just a CR followed by a BELL

Or, if you prefer the repr of the string:

print(repr(unhexlify(string).decode()))
# '\r\x07'

When doing byte-wise operations like XOR, it's often easier to work with bytes objects (since the individual bytes are treated as integers). From this question , then, we get:

ciphertext_1 = bytes.fromhex("4A17")
ciphertext_2 = bytes.fromhex("4710")

XORing the bytes can then be accomplished as in this question , with a comprehension. Then you can convert that to a string:

result = [c1 ^ c2 for (c1, c2) in zip(ciphertext_1, ciphertext_2)]
result = ''.join(chr(c) for c in result)

I would probably take a slightly different angle and create a bytes object instead of a list, which can be decoded into your string:

result = bytes(b1 ^ b2 for (b1, b2) in zip(ciphertext_1, ciphertext_2)).decode()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM