如何在Python中将文本编码为base64

98

我正在尝试将一个文本字符串编码为base64。

我尝试过这样做:

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

但是这会导致以下错误:

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

我该如何做到这一点?(使用Python 3.4)


1
看一下这个答案。base64是二进制到文本编码,我不知道为什么Python的base64模块不能自动将其转换回字符串... 维基百科 - S.B
9个回答

155

记得导入base64模块,同时b64encode需要以bytes类型作为参数。

import base64
b = base64.b64encode(bytes('your string', 'utf-8')) # bytes
base64_str = b.decode('utf-8') # convert bytes to string

7
如何在打印此内容时去掉前导的 b? - sukhvir
12
你需要使用某种编码方式(如 ascii 或 utf8)将它从字节转换成字符串。例如,可以使用 b'home'.decode('ascii') 进行解码。 - mgilson
类型错误:encode()缺少一个必需的位置参数:“output” - Eight Rice

32

要在py3中进行base64编码和解码,请使用以下代码:

import base64

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


def b64d(s):
    return base64.b64decode(s).decode()

8
这是正确的答案!base64是一种“二进制到文本”的编码方式。我不知道为什么Python的base64模块不能自动将其转换回字符串... - S.B
2
没错。为什么 .b64decode 函数需要一个字符串而不是字节?这些函数为什么不对称呢? - Pynchia
可能会有帮助为您的特定应用程序添加编码。例如,return base64.b64encode(s.encode('utf-8')).decode('utf-8') - undefined

31

结果证明这非常重要,以至于需要一个独立的模块...

import base64
base64.b64encode(b'your name')  # b'eW91ciBuYW1l'
base64.b64encode('your name'.encode('ascii'))  # b'eW91ciBuYW1l'

给我这个错误:`import base64
base64.b64encode(b'%s'%name) SyntaxError: multiple statements found while compiling a single statement`
- sukhvir
“>>>”是从我的终端提示符中复制的。请将其省略。 - mgilson
如何在打印输出时去掉前导的 b? - sukhvir
1
@sukhvir -- 请检查我在另一个答案中的回复 ;-) - mgilson
@StevenVascellaro -- 根据编码使用的字母表,可以使用base64.b64decode或其中一种变体 - mgilson
显示剩余3条评论

17

在Python 2中,以下代码可以不使用任何导入库就能正常运行:

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

(尽管这在Python3中不起作用)

2)在Python 3中,您需要导入base64并执行base64.b64decode('...')- 这也适用于Python 2。


1
小心这个!它会在输出中每58个字符添加换行符\n>>> 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.encode('base64') 'eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\neHh4\n' - Henrik Nordvik
根据BASE64标准(https://tools.ietf.org/html/rfc4648#section-3.3),必须忽略换行符: "请注意,这意味着任何相邻的回车/换行符(CRLF)字符构成“非字母字符”,并将被忽略。" 此外,新行字符也在标准中定义了 https://tools.ietf.org/html/rfc4648#section-3.1 "因此,MIME对base64编码数据的行长度强制限制为76个字符"。 - Tagar

5
看起来调用decode()函数是非常重要的,即使在对base64编码后的字符串进行base64.b64decode调用后,也需要使用decode()函数才能使用实际的字符串数据。因为不要忘记它始终返回字节文字。
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

4
为了兼容py2和py3,需进行以下操作。
import six
import base64

def b64encode(source):
    if six.PY3:
        source = source.encode('utf-8')
    content = base64.b64encode(source).decode('utf-8')

使用此方法与GCP部署管理器一起使用,对秘密进行base64编码。 - tarikki

2
虽然你当然可以使用base64模块,但你也可以使用codecs模块(在你的错误信息中提到)来进行二进制编码(意味着非标准和非文本编码)。
例如:
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")

这对于大量数据非常有用,因为您可以将它们链接在一起以获得压缩和json序列化的值:

最初的回答

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

Refs:


0
请使用以下代码:
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."

请考虑将您的内容翻译成 Python 3 可执行文件,因为原帖假定了这一点。 - dkato
这个问题已经有一些较旧的答案了。您能否评论一下您的回答有何优势? - Nico Haase
@NicoHaase,这是我开发的代码,可以将字符串从String转换为Base64或者反向转换。您可以直接将其作为Python脚本运行。 - Ujjawal Sharma
这并不真正回答我的问题:OP 并不是在寻求一个可以让一切成为可能的脚本,而是要纯粹地将字符串转换为 base64 的调用。 - Nico Haase
@NicoHaase 我自己也在寻找这个问题的解决方案,但是提供的解决方案对我来说不够。我在其他地方看到了代码,然后将整个解决方案写在了一个地方。 - Ujjawal Sharma

0
Base64编码是将二进制数据转换为ASCII字符串格式的过程,通过将该二进制数据转换为6位字符表示。当二进制数据(如图像或视频)在设计用于以纯文本(ASCII)格式传输数据的系统上传输时,使用Base64编码方法。

请点击link了解更多关于理解和使用base64编码的详细信息。

对于那些想要从头开始实现base64编码以便理解的人,这里提供了将字符串编码为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()))

输出:

$ ./testEncoder.py 
SGVsbG8=
MSAyIDEwIDEzIC03
QQ==

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接