195

How can I convert from hex to plain ASCII in Python?

Note that, for example, I want to convert "0x7061756c" to "paul".

Paul Reiners
  • 8,576
  • 33
  • 117
  • 202
  • I've tried a bunch of stuff I found here: http://docs.python.org/library/binascii.html – Paul Reiners Mar 09 '12 at 21:51
  • 2
    With the help of the link you just gave us, I found the function you were looking for. What _exactly_ did you try and why didn't it work? – Vincent Savard Mar 09 '12 at 21:54
  • 1
    I tried the following: >>> binascii.b2a_hqx("0x7061756c") '-(Jh-$Ba0c8fB`' >>> binascii.b2a_uu("0x7061756c") "*,'@W,#8Q-S4V8P \n" >>> binascii.b2a_base64("0x7061756c") 'MHg3MDYxNzU2Yw==\n' >>> binascii.b2a_qp("0x7061756c") '0x7061756c' >>> binascii.b2a_hex("0x7061756c") '30783730363137353663' >>> binascii.b2a_hex(0x7061756c) Traceback (most recent call last): File "", line 1, in TypeError: must be string or buffer, not int >>> – Paul Reiners Mar 09 '12 at 21:55
  • None of them worked, because none of them returned 'paul'. – Paul Reiners Mar 09 '12 at 21:55
  • 2
    Don't you mean "7-bit" ASCII? (Which is sort of silly because ASCII is only 7-bits.) A GUID is 128bits... –  Mar 09 '12 at 22:00

9 Answers9

259

A slightly simpler solution (python 2 only):

>>> "7061756c".decode("hex")
'paul'
ucczs
  • 609
  • 5
  • 15
cjm
  • 3,703
  • 1
  • 16
  • 18
  • 194
    there is no `.decode('hex')` on Python 3. [`.decode('hex')` uses `binascii.unhexlify()` on Python 2](http://hg.python.org/cpython/file/2.7/Lib/encodings/hex_codec.py#l27). – jfs Mar 10 '12 at 05:04
  • 2
    Thanks for pointing that out, I'm not as familiar with Python 3. This solution also won't work in 1 as far as I know. – cjm Mar 10 '12 at 17:46
  • 32
    `codecs.decode("7061756c", "hex")` works for Python 2 and Python 3. But it returns a `bytes()` string in Python 3. But that's reasonable for an ASCII string. – Mark Evans Aug 07 '15 at 08:46
176

No need to import any library:

>>> bytearray.fromhex("7061756c").decode()
'paul'
user4369081
  • 1,769
  • 1
  • 10
  • 2
  • 5
    Best solution for me (works with python 3) as it even accepts spaces : `bytearray.fromhex("70 61 75 6C").decode()` – Jona Feb 14 '17 at 09:10
  • bytearray.fromhex("70e4756c").decode(encoding="Latin1") 'päul' For those of us playing in binary, the extended characters choke on the default utf-8 decode, other than that, this is the most portable answer I see! Thanks! – grambo Nov 17 '17 at 16:14
  • 1
    Of course you have to know the *actual* encoding of the data if it is to be interpreted as text. Using `'latin-1'` will get rid of any errors but may well produce complete gibberish if the text is not actually Latin-1. – tripleee Oct 05 '19 at 06:56
  • In the interpreter, even the `repr` of the `bytearray` that is returned without `.decode()` is human readable, so for quickly checking something, you might get away without the `.decode()`. – xuiqzy Jan 30 '21 at 16:36
  • or better `bytes.fromhex("7061756c").decode()` since you don't need a mutable array and it's less to type. – maxschlepzig Sep 19 '21 at 10:28
  • why can't i convert the value `9c` ? – Ulf Gjerdingen Jun 01 '22 at 21:48
50
>>> txt = '7061756c'
>>> ''.join([chr(int(''.join(c), 16)) for c in zip(txt[0::2],txt[1::2])])
'paul'                                                                          

i'm just having fun, but the important parts are:

>>> int('0a',16)         # parse hex
10
>>> ''.join(['a', 'b'])  # join characters
'ab'
>>> 'abcd'[0::2]         # alternates
'ac'
>>> zip('abc', '123')    # pair up
[('a', '1'), ('b', '2'), ('c', '3')]        
>>> chr(32)              # ascii to character
' '

will look at binascii now...

>>> print binascii.unhexlify('7061756c')
paul

cool (and i have no idea why other people want to make you jump through hoops before they'll help).

andrew cooke
  • 45,717
  • 10
  • 93
  • 143
44

In Python 2:

>>> "7061756c".decode("hex")
'paul'

In Python 3:

>>> bytes.fromhex('7061756c').decode('utf-8')
'paul'
Julien
  • 1,810
  • 1
  • 16
  • 34
8
b''.fromhex('7061756c')

use it without delimiter

Husky
  • 89
  • 1
  • 1
6

Here's my solution when working with hex integers and not hex strings:

def convert_hex_to_ascii(h):
    chars_in_reverse = []
    while h != 0x0:
        chars_in_reverse.append(chr(h & 0xFF))
        h = h >> 8

    chars_in_reverse.reverse()
    return ''.join(chars_in_reverse)

print convert_hex_to_ascii(0x7061756c)
carloserivera
  • 151
  • 1
  • 7
  • +1 for a useful example, but you are not converting "hex" as the input but you are converting any integer to a hex string. You code will work equally as well with `print convert_hex_to_ascii(123456)`. – Mark Lakata Nov 01 '13 at 20:46
5

Tested in Python 3.3.2 There are many ways to accomplish this, here's one of the shortest, using only python-provided stuff:

import base64
hex_data ='57696C6C20796F7520636F6E76657274207468697320484558205468696E6720696E746F20415343494920666F72206D653F2E202E202E202E506C656565656173652E2E2E212121'
ascii_string = str(base64.b16decode(hex_data))[2:-1]
print (ascii_string)

Of course, if you don't want to import anything, you can always write your own code. Something very basic like this:

ascii_string = ''
x = 0
y = 2
l = len(hex_data)
while y <= l:
    ascii_string += chr(int(hex_data[x:y], 16))
    x += 2
    y += 2
print (ascii_string)
nihiser
  • 604
  • 1
  • 15
  • 28
Victor Barrantes
  • 2,258
  • 2
  • 20
  • 13
5

Alternatively, you can also do this ...

Python 2 Interpreter

print "\x70 \x61 \x75 \x6c"

Example

user@linux:~# python
Python 2.7.14+ (default, Mar 13 2018, 15:23:44) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> print "\x70 \x61 \x75 \x6c"
p a u l
>>> exit()
user@linux:~# 

or

Python 2 One-Liner

python -c 'print "\x70 \x61 \x75 \x6c"'

Example

user@linux:~# python -c 'print "\x70 \x61 \x75 \x6c"'
p a u l
user@linux:~# 

Python 3 Interpreter

user@linux:~$ python3
Python 3.6.9 (default, Apr 18 2020, 01:56:04) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> print("\x70 \x61 \x75 \x6c")
p a u l

>>> print("\x70\x61\x75\x6c")
paul

Python 3 One-Liner

python -c 'print("\x70 \x61 \x75 \x6c")'

Example

user@linux:~$ python -c 'print("\x70 \x61 \x75 \x6c")'
p a u l

user@linux:~$ python -c 'print("\x70\x61\x75\x6c")'
paul
  • 2
    This works fine without the spaces as well, and works fine in python3 with print(). – rjferguson Oct 07 '19 at 23:28
  • 1
    Yes, I put it on purpose to make it easier to see. Let me update the answer with Python 3 as well. –  May 23 '20 at 02:37
-1

No need to import anything, Try this simple code with example how to convert any hex into string

python hexit.py
Hex it>>some string


 736f6d6520737472696e67

python tohex.py
Input Hex>>736f6d6520737472696e67
some string
cat tohex.py


s=input("Input Hex>>")
b=bytes.fromhex(s)
print(b.decode())
  • 2
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 17 '22 at 13:23