Robby
Robby

Reputation: 1

Python3 bytes to string with real hex bytes

I've seen a lot of posts about this subject but I haven't found the solution I'm looking for (despite lot of attempts ...). In a nutshell, when migrating one of my libraries from Python2 to 3, whose main data model is based on hex strings like this '\xaa\xbb\xcc' (string length=3) I've encountered the (by now) known issue with the usage of binascii.a2b_hex('aabbcc') function, which gives '\xaa\xbb\xcc' in Python2 and b'\xaa\xbb\xcc' in Python3. Being the whole library based on this data model, including external libraries using it, it will take a lot of time to review the code line by line to migrate it to the bytes data model. In conclusion, I'm looking for a Python3 function doing the translation, i.e. b'\xaa\xbb\xcc' -> '\xaa\xbb\xcc' (string length=3) or 'aabbcc' -> '\xaa\xbb\xcc' (string length=3) many thanks in advance!

tried all hex()/binascii.hexlify()/format

Upvotes: 0

Views: 101

Answers (2)

user22400005
user22400005

Reputation:

Here's an alternative solution that uses the re module to achieve the same result:

import re

def bytes_to_escaped_hex(input_data):
    if isinstance(input_data, bytes):
        hex_string = ''.join([f'\\x{byte:02x}' for byte in input_data])
        return hex_string
    elif isinstance(input_data, str):
        hex_string = re.sub(r'(..)', r'\\x\1', input_data)
        return hex_string
    else:
        raise ValueError("Input must be bytes or hex string without '0x' prefix")

# Examples
bytes_data = b'\xaa\xbb\xcc'
hex_string = 'aabbcc'

escaped_hex1 = bytes_to_escaped_hex(bytes_data)
escaped_hex2 = bytes_to_escaped_hex(hex_string)

print(escaped_hex1)  # Output: '\xaa\xbb\xcc'
print(escaped_hex2)  # Output: '\xaa\xbb\xcc'

Upvotes: 0

Mark Ransom
Mark Ransom

Reputation: 308111

You can use the latin-1 codec which maps bytes to Unicode characters one for one, with the same values.

x = b'\xaa\xbb\xcc'
x = x.decode('latin-1')

Upvotes: 0

Related Questions