92

I am trying to encode a text string to base64.

i tried doing this :

name = "your name"
print('encoding %s in base64 yields = %s\n'%(name,name.encode('base64','strict')))

But this gives me the following error:

LookupError: 'base64' is not a text encoding; use codecs.encode() to handle arbitrary codecs

How do I go about doing this ? ( using Python 3.4)

sukhvir
  • 5,265
  • 6
  • 41
  • 43
  • 1
    Take a look at [this](https://stackoverflow.com/a/60531872/13944524) answer. base64 is **binary-to-text** encoding I don't know why python's base64 module doesn't convert it back to string by itself... [wikipedia](https://en.wikipedia.org/wiki/Base64) – S.B Aug 03 '21 at 19:26

9 Answers9

152

Remember to import base64 and that b64encode takes bytes as an argument.

import base64
b = base64.b64encode(bytes('your string', 'utf-8')) # bytes
base64_str = b.decode('utf-8') # convert bytes to string
rkachach
  • 16,517
  • 6
  • 42
  • 66
Alexander Ejbekov
  • 5,594
  • 1
  • 26
  • 26
29

It turns out that this is important enough to get it's own module...

import base64
base64.b64encode(b'your name')  # b'eW91ciBuYW1l'
base64.b64encode('your name'.encode('ascii'))  # b'eW91ciBuYW1l'
mgilson
  • 300,191
  • 65
  • 633
  • 696
28

For py3, base64 encode and decode string:

import base64

def b64e(s):
    return base64.b64encode(s.encode()).decode()


def b64d(s):
    return base64.b64decode(s).decode()
Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268
  • 8
    This is the correct answer ! base64 is **binary-to-text encoding** I don't know why python's `base64` module doesn't convert it back to string by itself... – S.B Aug 03 '21 at 19:22
  • 2
    Exactly. And why `.b64decode` expects a string and not bytes. Why aren't the functions symmetrical? – Pynchia Nov 11 '22 at 08:53
17

1) This works without imports in Python 2:

>>>
>>> 'Some text'.encode('base64')
'U29tZSB0ZXh0\n'
>>>
>>> 'U29tZSB0ZXh0\n'.decode('base64')
'Some text'
>>>
>>> 'U29tZSB0ZXh0'.decode('base64')
'Some text'
>>>

(although this doesn't work in Python3 )

2) In Python 3 you'd have to import base64 and do base64.b64decode('...') - will work in Python 2 too.

Tagar
  • 13,911
  • 6
  • 95
  • 110
  • 1
    Be careful with this one! It adds newlines `\n` into the output about every 58 character. `>>> 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.encode('base64') 'eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\neHh4\n'` – Henrik Nordvik May 13 '20 at 18:06
  • per BASE64 Standard https://tools.ietf.org/html/rfc4648#section-3.3 newline characters must be ignored: "Note that this means that any adjacent carriage return/line feed (CRLF) characters constitute "non-alphabet characters" and are ignored." Also the new line characters are defined in the Standard as well https://tools.ietf.org/html/rfc4648#section-3.1 "As such, MIME enforces a limit on line length of base 64-encoded data to 76 characters" – Tagar May 13 '20 at 18:41
5

It looks it's essential to call decode() function to make use of actual string data even after calling base64.b64decode over base64 encoded string. Because never forget it always return bytes literals.

import base64
conv_bytes = bytes('your string', 'utf-8')
print(conv_bytes)                                 # b'your string'
encoded_str = base64.b64encode(conv_bytes)
print(encoded_str)                                # b'eW91ciBzdHJpbmc='
print(base64.b64decode(encoded_str))              # b'your string'
print(base64.b64decode(encoded_str).decode())     # your string
Hafiz Hashim
  • 344
  • 3
  • 8
4

To compatibility with both py2 and py3

import six
import base64

def b64encode(source):
    if six.PY3:
        source = source.encode('utf-8')
    content = base64.b64encode(source).decode('utf-8')
NewBee
  • 1,331
  • 12
  • 13
2

Whilst you can of course use the base64 module, you can also to use the codecs module (referred to in your error message) for binary encodings (meaning non-standard & non-text encodings).

For example:

import codecs
my_bytes = b"Hello World!"
codecs.encode(my_bytes, "base64")
codecs.encode(my_bytes, "hex")
codecs.encode(my_bytes, "zip")
codecs.encode(my_bytes, "bz2")

This can come in useful for large data as you can chain them to get compressed and json-serializable values:

my_large_bytes = my_bytes * 10000
codecs.decode(
    codecs.encode(
        codecs.encode(
            my_large_bytes,
            "zip"
        ),
        "base64"),
    "utf8"
)

Refs:

TomDotTom
  • 6,238
  • 3
  • 41
  • 39
0

Use the below code:

import base64

#Taking input through the terminal.
welcomeInput= raw_input("Enter 1 to convert String to Base64, 2 to convert Base64 to String: ") 

if(int(welcomeInput)==1 or int(welcomeInput)==2):
    #Code to Convert String to Base 64.
    if int(welcomeInput)==1:
        inputString= raw_input("Enter the String to be converted to Base64:") 
        base64Value = base64.b64encode(inputString.encode())
        print "Base64 Value = " + base64Value
    #Code to Convert Base 64 to String.
    elif int(welcomeInput)==2:
        inputString= raw_input("Enter the Base64 value to be converted to String:") 
        stringValue = base64.b64decode(inputString).decode('utf-8')
        print "Base64 Value = " + stringValue

else:
    print "Please enter a valid value."
Ujjawal Sharma
  • 63
  • 1
  • 1
  • 7
  • Please consider to translate your into Python 3 executable, since original post assumed it. – dkato Jan 14 '18 at 15:21
  • There are some older answers to this question. Can you comment what makes your's better? – Nico Haase Jan 14 '18 at 15:36
  • @NicoHaase .. This code i had developed which can convert a string from String to Base64 and vice versa. You can directly run it as a python script. – Ujjawal Sharma Jan 14 '18 at 17:22
  • That does not really answer my question: the OP is not asking for a script that makes everything possible, but for the purest call of converting a string to base64 – Nico Haase Jan 14 '18 at 17:27
  • @NicoHaase I was looking for solution to this question myself but the solutions provided were not enough for me. I saw the code somewhere else and then i wrote the whole solution at one place. – Ujjawal Sharma Jan 14 '18 at 17:36
0

Base64 encoding is a process of converting binary data to an ASCII string format by converting that binary data into a 6-bit character representation. The Base64 method of encoding is used when binary data, such as images or video, is transmitted over systems that are designed to transmit data in a plain-text (ASCII) format.

Follow this link for further details about understanding and working of base64 encoding.

For those who want to implement base64 encoding from scratch for the sake of understanding, here's the code that encodes the string to base64.

encoder.py

#!/usr/bin/env python3.10

class Base64Encoder:

    #base64Encoding maps integer to the encoded text since its a list here the index act as the key
    base64Encoding:list = None

    #data must be type of str or bytes
    def encode(data)->str:
        #data = data.encode("UTF-8")

        if not isinstance(data, str) and not isinstance(data, bytes):
            raise AttributeError(f"Expected {type('')} or {type(b'')} but found {type(data)}")

        if isinstance(data, str):
            data = data.encode("ascii")

        if Base64Encoder.base64Encoding == None:
            #construction base64Encoding
            Base64Encoder.base64Encoding = list()
            #mapping A-Z
            for key in range(0, 26):
                Base64Encoder.base64Encoding.append(chr(key + 65))
            #mapping a-z
            for key in range(0, 26):
                Base64Encoder.base64Encoding.append(chr(key + 97))
            #mapping 0-9
            for key in range(0, 10):
                Base64Encoder.base64Encoding.append(chr(key + 48))
            #mapping +
            Base64Encoder.base64Encoding.append('+')
            #mapping /
            Base64Encoder.base64Encoding.append('/')


        if len(data) == 0:
            return ""
        length=len(data)

        bytes_to_append = -(length%3)+(3 if length%3 != 0 else 0)
        #print(f"{bytes_to_append=}")
        binary_list = []
        for s in data:
            ascii_value = s
            binary = f"{ascii_value:08b}" 
            #binary = bin(ascii_value)[2:]
            #print(s, binary, type(binary))
            for bit in binary:
                binary_list.append(bit)
        length=len(binary_list)
        bits_to_append = -(length%6) + (6 if length%6 != 0 else 0)
        binary_list.extend([0]*bits_to_append)

        #print(f"{binary_list=}")

        base64 = []

        value = 0
        for index, bit in enumerate(reversed(binary_list)):
            #print (f"{bit=}")
            #converting block of 6 bits to integer value 
            value += ( 2**(index%6) if bit=='1' else 0)
            #print(f"{value=}")
            #print(bit, end = '')
            if (index+1)%6 == 0:
                base64.append(Base64Encoder.base64Encoding[value])
                #print(' ', end="")

                #resetting value
                value = 0
                pass
        #print()

        #padding if there is less bytes and returning the result
        return ''.join(reversed(base64))+''.join(['=']*bytes_to_append)

testEncoder.py

#!/usr/bin/env python3.10

from encoder import Base64Encoder

if __name__ == "__main__":
    print(Base64Encoder.encode("Hello"))
    print(Base64Encoder.encode("1 2 10 13 -7"))
    print(Base64Encoder.encode("A"))

    with open("image.jpg", "rb") as file_data:
        print(Base64Encoder.encode(file_data.read()))

Output:

$ ./testEncoder.py 
SGVsbG8=
MSAyIDEwIDEzIC03
QQ==
Erik
  • 503
  • 1
  • 7
  • 26
Udesh
  • 2,415
  • 2
  • 22
  • 32