78

In Python 2 these all worked:

>>> "hello".encode("hex")
'68656c6c6f'
>>> b"hello".encode("hex")
'68656c6c6f'
>>> u"hello".encode("hex")
'68656c6c6f'

But in Python 3:

>>> "hello".encode("hex")
LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs

How to convert string to hex in Python 3?

wim
  • 338,267
  • 99
  • 616
  • 750
Stuart
  • 1,733
  • 4
  • 21
  • 34

10 Answers10

104

The hex codec has been chucked in 3.x. Use binascii instead:

>>> binascii.hexlify(b'hello')
b'68656c6c6f'
S.Lott
  • 384,516
  • 81
  • 508
  • 779
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
51

In Python 3.5+, encode the string to bytes and use the hex() method, returning a string.

s = "hello".encode("utf-8").hex()
s
# '68656c6c6f'

Optionally convert the string back to bytes:

b = bytes(s, "utf-8")
b
# b'68656c6c6f'
pylang
  • 40,867
  • 14
  • 129
  • 121
26

You've already got some good answers, but I thought you might be interested in a bit of the background too.

Firstly you're missing the quotes. It should be:

"hello".encode("hex")

Secondly this codec hasn't been ported to Python 3.1. See here. It seems that they haven't yet decided whether or not these codecs should be included in Python 3 or implemented in a different way.

If you look at the diff file attached to that bug you can see the proposed method of implementing it:

import binascii
output = binascii.b2a_hex(input)
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
26

The easiest way to do it in Python 3.5 and higher is:

>>> 'halo'.encode().hex()
'68616c6f'

If you manually enter a string into a Python Interpreter using the utf-8 characters, you can do it even faster by typing b before the string:

>>> b'halo'.hex()
'68616c6f'

Equivalent in Python 2.x:

>>> 'halo'.encode('hex')
'68616c6f'
simhumileco
  • 31,877
  • 16
  • 137
  • 115
  • Thank you @ner0 for your important comment! – simhumileco Dec 13 '19 at 08:31
  • 1
    No worries. If v3.4 or below is a requirement, this will do: `from binascii import hexlify str(hexlify(bytes('halo', encoding = 'utf-8')), 'ascii')` – ner0 Dec 13 '19 at 16:15
  • Is this because `.hex()` wasn't added until Python 3.5? A link to the changelog would have been really good in this answer as context :-) – Niels Abildgaard Feb 14 '22 at 11:03
24

binascii methodes are easier by the way

>>> import binascii
>>> x=b'test'
>>> x=binascii.hexlify(x)
>>> x
b'74657374'
>>> y=str(x,'ascii')
>>> y
'74657374'
>>> x=binascii.unhexlify(x)
>>> x
b'test'
>>> y=str(x,'ascii')
>>> y
'test'

Hope it helps. :)

iMagur
  • 721
  • 1
  • 6
  • 11
10

In Python 3, all strings are unicode. Usually, if you encode an unicode object to a string, you use .encode('TEXT_ENCODING'), since hex is not a text encoding, you should use codecs.encode() to handle arbitrary codecs. For example:

>>>> "hello".encode('hex')
LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
>>>> import codecs
>>>> codecs.encode(b"hello", 'hex')
b'68656c6c6f'

Again, since "hello" is unicode, you need to indicate it as a byte string before encoding to hexadecimal. This may be more inline with what your original approach of using the encode method.

The differences between binascii.hexlify and codecs.encode are as follow:

  • binascii.hexlify

    Hexadecimal representation of binary data.

    The return value is a bytes object.

    Type: builtin_function_or_method

  • codecs.encode

    encode(obj, [encoding[,errors]]) -> object

    Encodes obj using the codec registered for encoding. encoding defaults to the default encoding. errors may be given to set a different error handling scheme. Default is 'strict' meaning that encoding errors raise a ValueError. Other possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name registered with codecs.register_error that can handle ValueErrors.

    Type: builtin_function_or_method

Devy
  • 9,655
  • 8
  • 61
  • 59
8

base64.b16encode and base64.b16decode convert bytes to and from hex and work across all Python versions. The codecs approach also works, but is less straightforward in Python 3.

Community
  • 1
  • 1
Gabriel
  • 1,262
  • 12
  • 12
  • This is exactly what I needed! A cross-python version way of hex encoding & decoding. Thanks ^_^ `>>> import base64 >>> key = base64.b16encode(b'0123456789abcdef') >>> base64.b16decode(key) '0123456789abcdef'` – TrinitronX Apr 17 '14 at 06:03
3

Use hexlify - http://epydoc.sourceforge.net/stdlib/binascii-module.html

Ofir
  • 8,194
  • 2
  • 29
  • 44
2

Yet another method:

s = 'hello'

h = ''.join([hex(ord(i)) for i in s]);

# outputs: '0x680x650x6c0x6c0x6f'

This basically splits the string into chars, does the conversion through hex(ord(char)), and joins the chars back together. In case you want the result without the prefix 0x then do:

h = ''.join([str(hex(ord(i)))[2:4] for i in s]);

# outputs: '68656c6c6f'

Tested with Python 3.5.3.

Francis Laclé
  • 384
  • 2
  • 6
  • 22
0

str to hex:

>>> "hello".encode().hex()
'68656c6c6f'

bytes to hex:

>>> b"hello".hex()
'68656c6c6f'

bytes from hex:

>>> bytes.fromhex("68656c6c6f")
b'hello'

str from hex:

>>> bytes.fromhex("68656c6c6f").decode()
'hello'
wim
  • 338,267
  • 99
  • 616
  • 750