# base64 编码

### **base64是什么**

Base64编码，是由64个字符组成编码集：**26个大写字母A\~Z，26个小写字母a\~z，10个数字0\~9，符号“+”与符号“/”**。Base64编码的基本思路是**将原始数据的三个字节拆分转化为四个字节**，然后根据Base64的对应表，得到对应的编码数据。

当原始数据凑不够三个字节时，编码结果中会使用额外的**符号“=”**&#x6765;表示这种情况。

### **base64原理**

每一个base64的字符会对应有一个索引值（0-63）

<figure><img src="https://2169794061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaSpltJF2LxpVhG2ePEKS%2Fuploads%2Fvw4Z1uSocVfDvLBwxeIg%2Fbase64-1.png?alt=media&#x26;token=0fb07e8d-7a5e-4b40-b88d-b0fffb9239ad" alt=""><figcaption></figcaption></figure>

将you进行base64编码过程如下：

<figure><img src="https://2169794061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaSpltJF2LxpVhG2ePEKS%2Fuploads%2FH8A6tIFqfdOTY3PVaCzi%2Fbase64-2.png?alt=media&#x26;token=69a54d9f-2731-4498-a2c4-23881644bc68" alt=""><figcaption></figcaption></figure>

小于3个字符为一组的编码方式如：

<div align="left"><figure><img src="https://2169794061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaSpltJF2LxpVhG2ePEKS%2Fuploads%2FcePbRNmctEVOktYMAD6j%2Fbase64-3.png?alt=media&#x26;token=e4e6b562-2a63-4730-8d45-80bb02e1e9bc" alt=""><figcaption></figcaption></figure></div>

ASCII：

<div align="left"><figure><img src="https://2169794061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaSpltJF2LxpVhG2ePEKS%2Fuploads%2FoamZncjhAPpaDeXodiCH%2Fbase64-4.png?alt=media&#x26;token=c2c88056-8db5-43b1-a721-7c1da2b684bf" alt=""><figcaption></figcaption></figure></div>

### **base64测试**

#### base64编码示例：

```python
import base64
​
# 将原始数据转化为二进制/字节数据
data = "you".encode("utf-8")
print(data)
​
# 把字节转化成b64
bs = base64.b64encode(data).decode()
# 使用 base64.b64encode() 进行 Base64 编码，返回的是字节数据
# 使用 .decode() 将字节数据转换为字符串
print(bs)
​

bs = "yo".encode("utf-8")
# 把字节转化成b64
print(base64.b64encode(bs).decode())
​
# 猜测结果
bs = "y".encode("utf-8")
# 把字节转化成b64
print(base64.b64encode(bs).decode())
```

#### base64解码示例：

注意, base64编码处理后的字符串长度. 一定是4的倍数（因为Base64编码的基本思路是**将原始数据的三个字节拆分转化为四个字节**）. 如果在网页上看到有些密文的b64长度不是4的倍数. 会报错

```python
import base64
​
s = "eW91"
ret = base64.b64decode(s)
print(ret) #正确
​
s = "eW91eQ=="
ret = base64.b64decode(s)
print(ret) #正确
​
s = "eW91eQ"
ret = base64.b64decode(s)
print(ret) #报错，s不是4的倍数
```

如果不是4的倍数如何处理呢？解决思路. 使用=填充为4的倍数即可

```python
s = "eW91eQ"
#填充为4的倍数
s += ("=" * (4 - len(s) % 4))
print("填充后", s)
ret = base64.b64decode(s).decode()
print(ret)
```

#### base64 编码的优点：

* 算法是编码，不是压缩，编码后只会增加字节数（一般是比之前的多1/3，比如之前是3， 编码后是4）
* 算法简单，基本不影响效率
* 算法可逆，解码很方便，不用于私密传输

### 示例

#### 编码

```python
import base64

data = 'Hello'.encode('utf-8')  # 将字符串 "Hello" 转换为 UTF-8 编码的字节数据
print(data)  # 输出字节数据（即 b'Hello'）

bs_data = base64.b64encode(data).decode()  
# 使用 base64.b64encode() 进行 Base64 编码，返回的是字节数据
# 使用 .decode() 将字节数据转换为字符串

print(bs_data)  # 输出 Base64 编码后的字符串：SGVsbG8=
```

#### 解码

```python
import base64

bs_data = "SGVsbG8="  # 这是一个 Base64 编码后的字符串

data = base64.b64decode(bs_data).decode()  
# 使用 base64.b64decode() 进行 Base64 解码，返回的是字节数据
# 使用 .decode() 将字节数据转换为字符串

print(data)  # 输出解码后的字符串：Hello
```
