3

Input:

'0x0 0x48 0x65 0x6c 0x6c 0x6f 0x8E 0x21'

Output:

Hello!

Current Solution:

    s = []
    birary_data = '0x0 0x48 0x65 0x6c 0x6c 0x6f 0x8E 0x21'.replace(' ', '').split('0x')
    for c in birary_data:
        if len(c) > 1:
            s.append(bytes.fromhex(c).decode('utf-8', 'ignore'))
    print("".join(s))

Need help with:

Could anyone suggest a more elegant solution, please?

2
  • Why do you think your solution is not elegant ? Commented Mar 5, 2020 at 11:38
  • @MauriceMeyer, it feels like I'm doing extra and unnecessary steps. However, there could a very simple solution, like birary_data.decode('hex') Commented Mar 5, 2020 at 11:41

5 Answers 5

4

Try this:

data = '0x0 0x48 0x65 0x6c 0x6c 0x6f 0x8E 0x21'
string = "".join([chr(int(item, 16)) for item in data.split()])
print(string)

Output:

Hello!
Sign up to request clarification or add additional context in comments.

2 Comments

I always forget that int can take a base, this is a good solution
Doesn't this have a leading null byte and something else before the last char?
4

Another option is to remove 3 characters (or less) length substrings, 0x and white spaces. bytes.fromhex can handle a string like '48656c6c6f8E21'

binary_data = '0X0 0x48 0x65 0x6c 0x6c 0x6f 0x8E 0x21'
binary_data = re.sub(r'\b\w{3}\b|\s?0x', '', binary_data)
print(bytes.fromhex(binary_data).decode('utf-8', 'ignore'))

1 Comment

why not change your pattern to r'\b\w{3}\b|\s?0x' to get '48656c6c6f8E21' directly?
3

You can use the below one Here in the code i am first splitting the hex according to white-space and then iterating and joining the character i get.

a = '0x0 0x48 0x65 0x6c 0x6c 0x6f 0x8E 0x21'
print(''.join(chr(int(i, 16)) for i in a.split()))

Comments

3

The builtin bytes.fromhex() is very nearly all we need. There are however two problems we need to get around:

  • The null byte at the front
  • The invalid char in position 6 (0x8E)
import re

data = '0x0 0x48 0x65 0x6c 0x6c 0x6f 0x8E 0x21'

string = bytes.fromhex(re.sub('0x(0 )?', '', data)).decode('utf-8', 'ignore')

The regex will take care of both stripping the null byte and formatting the string correctly for bytes.fromhex(). The ignore in the decode will skip the bad byte.

Comments

2
birary_data = '0x0 0x48 0x65 0x6c 0x6c 0x6f 0x8E 0x21'.replace('0x', '').split()
print(bytearray.fromhex(''.join(c for c in birary_data if len(c) > 1)).decode('utf-8', 'ignore'))

Output:

Hello!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.