0

Am writing a program with python gui. that program concept is when we run the prgm it will ask to open one file(witch contains hexa decimal value as TASK.txt) with read mode. am storing the data of one line in one variable. how can i convert that data into ascii value. Am new to python. This is my code:

import binascii
import base64
from tkinter import *
from tkinter.filedialog import askopenfilename

def callback():
    with open(askopenfilename(),'r') as r:
        next(r)
        for x in r:
            z = str(x[1:-2])
            if len(z) % 2:
                z = '0' + 'x' + z
            print(binascii.unhexlify(z))

a = Button(text='select file', command=callback)
a.pack()

mainloop()

This is the error I am getting:

Exception in Tkinter callback
Traceback (most recent call last):
  File "D:\python sw\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\LENOVO\Downloads\hex2.py", line 16, in callback
    print(binascii.unhexlify(z))
binascii.Error: Non-hexadecimal digit found"""
S.S
  • 1
  • 2
  • That Tkinter stuff is irrelevant. Question code should be a [mcve] that focuses on the actual problem. The error message says that you have characters in the arg to `binascii.unhexlify` that aren't valid hex digits. Do **not** prepend `'0x'` to the hex data. There may be other problems with that data. Can you post a small typical sample of that data? – PM 2Ring Feb 14 '17 at 06:57
  • Thank you for the reply this is my data H247314748F8 HA010001FD – S.S Feb 14 '17 at 17:22

1 Answers1

0

Just reread your question correctly, new answer:

  1. Do not prefix with 0x since it does not work with unhexlify and won't even make the string-length even.
  2. You need an even string length, since each pair of hex-digits represent one byte (being one character)
  3. unhexlify returns a byte array, which can be decoded to a string using .decode()
  4. As pointed out here you don't even need the import binascii and can convert hex-to-string with bytearray.fromhex("7061756c").decode()
list(map(lambda hx: bytearray.fromhex(hx).decode(),"H7061756c H7061756c61".replace("H","").split(" ")))

Returns ['paul', 'paula']

What I wrote before I thoroughly read your question may still be of use

As PM 2Ring noted, unhexilify only works without prefixes like 0x. Your hex-strings are separated by spaces and are prefixed with H, which must be removed. You already did this, but I think this can be done in a nicer way:

r = "H247314748F8 HA010001FD" # one line in your file
z_arrary = data.replace("H","").split(" ") 
# this returns ['247314748F8','A010001FD']
# now we can apply unhexlify to all those strings:
unhexed = map(binascii.unhexlify, z_array)
# and print it.
print(list(unhexed))

This will throw you an Error: Odd-length string. Make sure you really want to unhexilify your data. As stated in the docs you'll need an even number of hexadecimal characters, each pair representing a byte.

If you want to convert the hexadecimal numbers to decimal integers numbers instead, try this one:

list(map(lambda hx: int(hx,16),"H247314748F8 HA010001FD".replace("H","").split(" ")))

int(string, base) will convert from one number system (hexadecimal has base 16) to decimal (with base 10).

** Off topic **

        if len(z) % 2:
            z = '0' + 'x' + z

Will lead to z still being of uneven length, since you added an even amount of characters.

Community
  • 1
  • 1
nitzel
  • 1,565
  • 14
  • 14