1

Edited:

The code below is reading a file (an image in this example) in binary mode:

with open("img_80px.png", mode='rb') as file:
    file_content = file.read()
    binary_data = []
    for i in file_content:
        binary_data.append(i)

Now, printing out file_content will give us a string of hex values in binary b' ' format:

b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00P\x00\x00\x00<
\x08\x06\x00\x00\x00\xf1\'=\x8c\x00\x00\x00\tpHYs\x00\x00\x0fa
\x00\x00\x0fa\x01\xa8?\xa7i\x00\x009\xeeiTXtXML:com.adobe.xmp
\x00\\x00\x00\x00\x00<?xpacket begin="\xef\xbb\xbf" id="W5M0MpCehiHzreSzNTczkc9d"?> 
\n<x:xmpmeta xmlns:x="adobe:ns:meta/" 
x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 

 ....'

So, the code converts this binary string into the list of numbers by going through file_content and appending each bit into the binary_data (not sure if it's the best way, not sure why it even works), so we're getting this:

[137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13 ....]

The question is, how do I convert this list back into that b'' hex binary string or whatever it is? As you can see, it has \x values and metadata in plain text there. Not sure how to convert it back.

If this way of conversion is disrative, could you suggest another way to convert binary in to a string of integers and back?

I tried doing this:

binary_data_string = "".join(map(str, binary_data))

with open("edited_img_80px.png", mode='wb') as edited_file: 
    binary_hex = bytes.fromhex(binary_data_string)
    edited_file.write(binary_hex)

it throws an error:

ValueError: non-hexadecimal number found in fromhex() arg at position 58313

And I also tried to not convert it to a string to preserve the information about each converted item in the list and be able to convert it back into the binary, but I get:

TypeError: fromhex() argument must be str, not list
Community
  • 1
  • 1
Un1
  • 3,874
  • 12
  • 37
  • 79
  • "how do I convert this string back" - not possible. You threw away the information of where one byte ends and the next begins. – user2357112 Jul 21 '17 at 21:03
  • For example, `b'\x01\x01'` and `b'\x0b'` produce identical output. – user2357112 Jul 21 '17 at 21:05
  • Have you checked that `binary_data_string` contains the data you expect it to? The error you are getting sounds like your string does not contain only 0-9,A-F, so it may not have been converted correctly. – beenjaminnn Jul 21 '17 at 21:10
  • @user2357112 thanks for the comment, I've changed the question, could you please take a look at it again and tell me if NOT joining it into a single string prevents the data loss you described? – Un1 Jul 21 '17 at 21:27
  • @beenjaminnn yeah, it says `at position 58313` it's the last character in the string, the string is 58313 chars long. Not sure why it doesn't like it – Un1 Jul 21 '17 at 21:29
  • Possible duplicate of [List of integers into string (byte array) - python](https://stackoverflow.com/questions/3470398/list-of-integers-into-string-byte-array-python) – beenjaminnn Jul 21 '17 at 21:46
  • 1
    Thanks for editing your question! Since you're using python3, take a look at: https://stackoverflow.com/a/35219695/2426888 – beenjaminnn Jul 21 '17 at 21:47
  • @beenjaminnn yes! That's it! It's exactly what I need, I just did what one of the answers there suggested: `bytes(binary_data)` converts the list back to binary. You can answer the question with `bytes()` I'll accept it to increase your reputation a bit. It does exactly what I asked for – Un1 Jul 21 '17 at 21:50

1 Answers1

2

Since you're using Python 3, you can do this:

>>>numbers = [222, 173, 190, 239]
>>>bytes(numbers)
b'\xde\xad\xbe\xef'

Cheers!

beenjaminnn
  • 752
  • 1
  • 11
  • 23
  • Cheers mate! Hopefully someone else will find this useful as well, I've been trying to find it in google for 15 minutes, sometimes it's hard to describe such a simple thing. – Un1 Jul 21 '17 at 22:06