30

I want to convert a simple HEX string such as 10000000000002ae to Base64.

The hex string is to be converted to bytes, and the bytes are then encoded to base64 notation, so the expected output for that string: EAAAAAAAAq4=

I found a tool online: http://tomeko.net/online_tools/hex_to_base64.php?lang=en

But I have a bunch of HEX values that I need to convert in a script.

2
  • I had to go to the tool itself and run an experiment to see what was meant. The tool decodes the hex notation to bytes, then converts that binary data to base64. Commented Nov 14, 2015 at 2:03
  • Always try to break down your problem into sub-problems, and try to understand what the conversion actually does. The two steps involved here are both already answered widely here on Stack Overflow and elsewhere. Commented Nov 14, 2015 at 2:06

7 Answers 7

37

Edit 26 Aug 2020: As suggested by Ali in the comments, using codecs.encode(b, "base64") would result in extra line breaks for MIME syntax. Only use this method if you do want those line breaks formatting.

For a plain Base64 encoding/decoding, use base64.b64encode and base64.b64decode. See the answer from Ali for details.


In Python 3, arbitrary encodings including Hex and Base64 has been moved to codecs module. To get a Base64 str from a hex str:

import codecs

hex = "10000000000002ae"
b64 = codecs.encode(codecs.decode(hex, 'hex'), 'base64').decode()
4
  • 3
    That tacks on a newline at the end for some reason.
    – user124384
    Commented Jan 21, 2019 at 3:34
  • 1
    @user124384 - Tack a .replace("\n", "") at the end.
    – bitinerant
    Commented Jul 18, 2019 at 19:04
  • 1
    Yeah, it's strange that it tacks on a newline after the decode. Is it for pretty printing? Commented Jul 1, 2020 at 5:36
  • 3
    WARNING! With this answer you will get a newline after every 76 bytes of output because it converts to multiline MIME base64. See my answer for a proper conversion.
    – Ali
    Commented Aug 26, 2020 at 10:21
34
from base64 import b64encode, b64decode

# hex -> base64
s = 'cafebabe'
b64 = b64encode(bytes.fromhex(s)).decode()
print('cafebabe in base64:', b64)

# base64 -> hex
s2 = b64decode(b64.encode()).hex()
print('yv66vg== in hex is:', s2)
assert s == s2

This prints:

cafebabe in base64: yv66vg==
yv66vg== in hex is: cafebabe

The relevant functions in the documentation, hex to base64:

Base64 to hex:


I don't understand why many of the other answers are making it so complicated. For example the most upvoted answer as of Aug 26, 2020:

  • There is no need for the codecs module here.
  • The codecs module uses base64.encodebytes(s) under the hood (see reference here), so it converts to multiline MIME base64, so you get a new line after every 76 bytes of output. Unless you are sending it in e-mail, it is most likely not what you want.

As for specifying 'utf-8' when encoding a string, or decoding bytes: It adds unnecessary noise. Python 3 uses utf-8 encoding for strings by default. It is not a coincidence that the writers of the standard library made the default encoding of the encode/decode methods also utf-8, so that you don't have to needlessly specify the utf-8 encoding over and over again.

2
  • Thanks for pointing this out! I personally use base.b64<encode|decode> for quite a few years now. I didn’t realise the MIME syntax implied in the codecs library until now. I’ve edited my answer with a link to yours at the beginning.
    – Eana Hufwe
    Commented Aug 26, 2020 at 14:35
  • @EanaHufwe OK, I am glad that we have cleaned this up!
    – Ali
    Commented Aug 26, 2020 at 15:08
15

Python 2 has native support for both HEX and base64 encoding:

encoded = HEX_STRING.decode("hex").encode("base64")

(if you are using Python 3, see Eana Hufwe or Ali's answers instead)

2
  • 1
    WARNING! With Eana Hufwe's answer you will get a newline after every 76 bytes of output because it converts to multiline MIME base64. See my answer for a proper conversion.
    – Ali
    Commented Aug 26, 2020 at 10:23
  • This answer is useless for Python 3, and so it should be deleted. Python 2 is obsolete.
    – Asclepius
    Commented Nov 22, 2020 at 17:23
12

The tool you link to simply interprets the hex as bytes, then encodes those bytes to Base64.

Either use the binascii.unhexlify() function to convert from a hex string to bytes, or use the bytes.fromhex() class method. Then use the binascii.b2a_base64() function to convert that to Base64:

from binascii import unhexlify, b2a_base64

result = b2a_base64(unhexlify(hex_string))

or

from binascii import b2a_base64

result = b2a_base64(bytes.fromhex(hex_string))

In Python 2, you can also use the str.decode() and str.encode() methods to achieve the same:

result = hex_string.decode('hex').encode('base64')

In Python 3, you'd have to use the codecs.encode() function for this.

Demo in Python 3:

>>> bytes.fromhex('10000000000002ae')
b'\x10\x00\x00\x00\x00\x00\x02\xae'
>>> from binascii import unhexlify, b2a_base64
>>> unhexlify('10000000000002ae')
b'\x10\x00\x00\x00\x00\x00\x02\xae'
>>> b2a_base64(bytes.fromhex('10000000000002ae'))
b'EAAAAAAAAq4=\n'
>>> b2a_base64(unhexlify('10000000000002ae'))
b'EAAAAAAAAq4=\n'

Demo on Python 2.7:

>>> '10000000000002ae'.decode('hex')
'\x10\x00\x00\x00\x00\x00\x02\xae'
>>> '10000000000002ae'.decode('hex').encode('base64')
'EAAAAAAAAq4=\n'
>>> from binascii import unhexlify, b2a_base64
>>> unhexlify('10000000000002ae')
'\x10\x00\x00\x00\x00\x00\x02\xae'
>>> b2a_base64(unhexlify('10000000000002ae'))
'EAAAAAAAAq4=\n'
2

Python has native support for both HEX and base64 encoding:

import base64

def main():
    b16 = bytearray('10000000000002ae'.decode('hex'))
    b64 = base64.b64encode(b16)

    print b64
2

In case someone is looking for a python3 one-liner (bash):

python -c "import codecs as c; print(c.encode(c.decode('10000000000002ae', 'hex'), 'base64').decode())"
2

In python3, you may use bytes.fromhex to bytes, use base64 package convert bytes to base64

hex_str = '01'
encoded_str = base64.b64encode(bytes.fromhex(hex_str)).decode('utf-8')
decoded_str = base64.b64decode(encoded_str.encode('utf-8')).hex()

Not the answer you're looking for? Browse other questions tagged or ask your own question.