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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.