python中base64库详解 - vip共享吧
  • 网站首页
  • IT技术笔记
    • Java教程
    • MySql数据库
    • PHP开发
    • Python教程
    • JavaScript
    • SEO优化
    • 常用工具
  • 好资源福利
    • 会员账号共享
  • 网站模板源码
    • 小程序源码
    • 网站源码
  • 共享网络资源
  • 更多功能
    • 留言吐槽
    • 文章归档
    • 我的邻居
    • 史上今日
    • 视频解析
    • 高清壁纸
    • 公告动态
    • 广告合作
    • 关于我们


导航菜单
  • 网站首页
  • IT技术笔记
    • Java教程
    • MySql数据库
    • PHP开发
    • Python教程
    • JavaScript
    • SEO优化
    • 常用工具
  • 好资源福利
    • 会员账号共享
  • 网站模板源码
    • 小程序源码
    • 网站源码
  • 共享网络资源
  • 更多功能
    • 留言吐槽
    • 文章归档
    • 我的邻居
    • 史上今日
    • 视频解析
    • 高清壁纸
    • 公告动态
    • 广告合作
    • 关于我们
Python

python中base64库详解

2024/9/5 韩俊  Python教程 762 0

我们知道在计算机中任何数据都是按字节存储的,有的复杂的数据(比如汉字)可能由多个字节表示,简单(比如单个英文字符)的由 1 个字节表示,字节是内存中基本的存储单位。

我们知道一个字节可表示的范围是 0 ~ 255(十六进制:0x00 ~ 0xFF),其中 ascii 值的范围为 0 ~ 127(十六进制:0x00 ~ 0x7F);而超越 ascii 范围的 128~255(十六进制:0x80 ~ 0xFF)之间的值是不可见字符。当然也并不是所有的 ascii 都是可见的,ascii 中只有 95 个可见字符(范围为 32 ~ 126),其余的 ascii 为不可见字符,本节后面我们会列出所有可见的 ascii 和 不可见的 ascii。

当不可见字节流在网络上传输时,比如说从 A 计算机传到 B 计算机,往往要经过多个路由设备,由于不同的设备(特指老的路由设备)对字节流的处理方式有一些不同,这样那些不可见字节就有可能被处理错误,这是不利于传输的。所以就先把数据先做一个 base64 编码,统统变成可见字节,也就是 ascii 码可表示的可见字符,确保数据可靠传输。base64 的内容是有 0 ~9,a ~z,A ~Z,+,/组成,正好 64 个字符,这些字符是在 ascii 可表示的范围内,属于 95 个可见字符的一部分。

对于现在的路由设备,只要是文本字符(无论是否是可见字符)都可以转为字节流(字节类型数据)在网络上传输。而字节类型的数据(图片,音频,视频,语音等二进制数据), 本身就是字节流,所以可以直接在网络上传输。但是,在企业开发中,我们为了一致性约定,往往对要发送的数据先进行序列化,然后再编码(encoding)为字节流在网络上发送,而对方收到数据后,要先把字节流解码(decoding)为字符串,然后再反序列化还原为原始数据。

我们往往使用 json 对要发送的数据进行序列化,因为 json 有多语言支持,而 pickle 只有 Python 语言本身支持,我们知道通信的另一方不一定也是使用 Python 语言,所以,我们对网络传输的数据一般不使用 pickle 进行序列化。然而,json 无法序列化字节类型的数据,那我们如果想发送字节类型的数据(图片,音频,视频,语音等二进制数据),应该怎么办呢?

有些同学可能会想,我们可以把字节类型数据转为字符串类型数据,然后再使用 json 序列化,然而不幸的是,对于字节类型的图片,音频,视频,语音等二进制数据里面含有很多不可见字节,而这些不可见字节无法转为字符串。但是,我们可以先用 base64 把这些不可见字节数据编码为可见字节数据,然后再转为字符串类型,然后在通过 json 进行序列化,然后再编码为字节流通过网络发送出去。而对方收到数据后,要先把字节流解码为字符串,然后再反序列化,然后再转为字节类型数据,然后再使用 base64 解码还原成原始数据。

最后,大家可能要问,字节类型的数据(图片,音频,视频,语音等二进制数据)本身就可以直接通过网络传输,为什么还要序列化?在此,我再告诉大家,你项目中要传输的数据不只有这些二进制吧,应该还需要包容其它类型的数据(int,list,dict等等),而这些结构化类型数据,必须要序列化后,才能通过网络传输。通信双方约定的就是发送的东西都是序列化后数据,这样方便对通信双方的数据类型进行还原。你没必要只对其它类型的数据序列化,对字节类型数据不序列化,这样反而增加了业务逻辑。

base64 的使用

base64 是 Python 内建模块,我们只需要 import 导入模块就可以使用,我们可以把超越 ascii 范围的字符用 base64 编码为可见字符,注意 base64只能编码字节类型数据。

import base64

mydata = b"\x80"  # \x80 换成十进制为 128,超越了 ascii 范围,为不可见字节
datab64 = base64.b64encode(mydata)  # 编码为 base64 的可见字节
print(datab64)

mydata = base64.b64decode(datab64)
print(mydata)  # 解码为不可见字节 \x80

base64 自己有一套算法可以把我们的字节编码成 ascii 范围内的字节,当然它不关心我们给的字节是不是可见字节,如果是可见字节同样要编码,如果是不可见字节则会编码成可见字节。

import base64

dataone = "p".encode("utf8")    # 可见字节
datatwo = "共".encode("utf8")   # 不可见字节

print(base64.b64encode(dataone))  # 编码可见字节为可见字节
print(base64.b64encode(datatwo))  # 编码不可见字节为可见字节

base64 编码会把 3 个字节的字节类型数据编码为 4 个可见字节的字节类型数据,如果要编码的字节类型数据不是 3 的倍数,最后会剩下 1 个或 2 个字节,base64 会在编码的末尾加上 1 个或 2 个 = 号,表示补了多少字节,解码的时候,会自动去掉。

import base64

strone = "p".encode("utf8")             # 1个字节
strtwo = "py".encode("utf8")            # 2 个字节
strthree = "pyt".encode("utf8")         # 3 个字节
strfour = "pyth".encode("utf8")         # 4 个字节
strfive = "pytho".encode("utf8")        # 5 个字节
strsix = "python".encode("utf8")        # 6 个字节
strseven = "毛票票".encode("utf8")        # utf-8 编码,每个汉字一般占 3 个字节
streight = "毛票票python".encode("utf8")  # utf-8 编码,每个汉字一般占 3 个字节,英文占 1 个字节

print(base64.b64encode(strone))    # 按 3 个字节(缺 2 个,补齐 2 个 =)编码成 4 个字节 cA==
print(base64.b64encode(strtwo))    # 按 3 个字节(缺 1 个,补齐 1 个 =)编码成 4 个字节 cHk=
print(base64.b64encode(strthree))  # 按 3 个字节编码成 4 个字节 cHl0
print(base64.b64encode(strfour))   # 按 6 个字节(缺 2 个,补齐 2 个 =)编码成 8 个字节 cHl0aA==
print(base64.b64encode(strfive))   # 按 6 个字节(缺 1 个,补齐 1 个 =)编码成 8 个字节 cHl0aG8=
print(base64.b64encode(strsix))    # 按 6 个字节编码成 8 个字节 cHl0aG9u
print(base64.b64encode(strseven))  # 按 6 个字节编码成 8 个字节 6ICB6bif
print(base64.b64encode(streight))  # 按 12 个字节编码成 16 个字节 6ICB6bifcHl0aG9u

我们可以对用 base64 编码后的字节进行解码。

import base64

dataone = "python".encode("utf8")    # 可见字节
datatwo = "毛票票".encode("utf8")       # 不可见字节

dataone = base64.b64encode(dataone)  # 编码可见字节 "python"
datatwo = base64.b64encode(datatwo)  # 编码不可见字节 "老鸟" 为可见字节

print(base64.b64decode(dataone))     # 解码 base64 编码后的字节
print(base64.b64decode(datatwo))     # 解码 base64 编码后的字节

由于 base64 编码后可能出现字符 + 和 /,在网页上传输数据,我们用 get 方式传输字符串时,字符 + 和 / 在 URL 中有特殊用途,就不能直接作为参数,所以又有一种 "url safe" 的 base64 编码,其实就是把字符 + 和 / 分别变成 - 和 _。

import base64

mydata = b"\xfb\xef\xff"
print(base64.b64encode(mydata))          # 编码为 ++//,但是 + 和 / 在 url 中有特殊用途,不能作为参数
print(base64.urlsafe_b64encode(mydata))  # 编码为 --__,很好。

在互联网上传输图片,音乐,视频,语音等等这些二进制数据是常用的需求, 本节开头部分,我们说过,最好要对所有发送的数据进行序列化后再进行网络传输。所以,正规的流程是:先用 base64 把这些不可见字节数据编码为可见字节数据,然后再转为字符串类型,然后在通过 json 进行序列化,然后再编码为字节流通过网络发送出去。而对方收到数据后,要先把字节流解码为字符串,然后再反序列化,然后再转为字节类型数据,然后再使用 base64 解码还原成原始数据。

import base64
import json

f = open("d:/test.png", "rb")  # 确保你计算机中存在 d:/test.png
imgdata = f.read()             # 二进制图片数据
f.close()

imgdatab64 = base64.b64encode(imgdata)     # 编码为可见字节
imgdatab64str = imgdatab64.decode("utf8")  # 转为字符串
jsondata = json.dumps(imgdatab64str)       # json 序列化
bytesdata = jsondata.encode("utf8")        # 编码为字节类型在网络上传输


'''
通过网络传输......,
对方机器收到后,先反序列化,最后用 base64 进行解码
'''

bytesdata_recv = bytesdata                     # 收到网络上发来的字节流
jsondata_recv = bytesdata_recv.decode("utf8")  # 解码为字符串
strdata_recv = json.loads(jsondata_recv)       # json 反序列化
bytesdata_recv = strdata_recv.encode("utf8")   # 转为字节类型数据
imgdata = base64.b64decode(bytesdata_recv)     # 解码为原始数据

# 把从网络上收到的图片数据写入磁盘,文件名字为 copy.png
f = open("d:/copy.png", "wb")
imgdata = f.write(imgdatab64)
f.close()

注意:base64 仅仅是把字节类型数据按照一定的算法转化为属于 ascii 范围内的可见字节类型数据,但不要作为加密行为。

ascii 可见和不可见字符表

我们知道一个字节的大小超越 ascii 编码的都是不可见字符,但 ascii 编码也不是所有字符都是可见的,在 128 个 ascii 中,只有 95 个可见字符,下表为 ascii 中可见字符表。

二进制 十进制 十六进制 图形
0010 0000 32 20 (空格)(␠)
0010 0001 33 21 !
0010 0010 34 22 "
0010 0011 35 23 #
0010 0100 36 24 $
0010 0101 37 25  %
0010 0110 38 26 &
0010 0111 39 27 '
0010 1000 40 28 (
0010 1001 41 29 )
0010 1010 42 2A *
0010 1011 43 2B +
0010 1100 44 2C ,
0010 1101 45 2D -
0010 1110 46 2E .
0010 1111 47 2F /
0011 0000 48 30 0
0011 0001 49 31 1
0011 0010 50 32 2
0011 0011 51 33 3
0011 0100 52 34 4
0011 0101 53 35 5
0011 0110 54 36 6
0011 0111 55 37 7
0011 1000 56 38 8
0011 1001 57 39 9
0011 1010 58 3A :
0011 1011 59 3B ;
0011 1100 60 3C <
0011 1101 61 3D =
0011 1110 62 3E >
0011 1111 63 3F ?
 
二进制 十进制 十六进制 图形
0100 0000 64 40 @
0100 0001 65 41 A
0100 0010 66 42 B
0100 0011 67 43 C
0100 0100 68 44 D
0100 0101 69 45 E
0100 0110 70 46 F
0100 0111 71 47 G
0100 1000 72 48 H
0100 1001 73 49 I
0100 1010 74 4A J
0100 1011 75 4B K
0100 1100 76 4C L
0100 1101 77 4D M
0100 1110 78 4E N
0100 1111 79 4F O
0101 0000 80 50 P
0101 0001 81 51 Q
0101 0010 82 52 R
0101 0011 83 53 S
0101 0100 84 54 T
0101 0101 85 55 U
0101 0110 86 56 V
0101 0111 87 57 W
0101 1000 88 58 X
0101 1001 89 59 Y
0101 1010 90 5A Z
0101 1011 91 5B [
0101 1100 92 5C \
0101 1101 93 5D ]
0101 1110 94 5E ^
0101 1111 95 5F _
 
二进制 十进制 十六进制 图形
0110 0000 96 60 `
0110 0001 97 61 a
0110 0010 98 62 b
0110 0011 99 63 c
0110 0100 100 64 d
0110 0101 101 65 e
0110 0110 102 66 f
0110 0111 103 67 g
0110 1000 104 68 h
0110 1001 105 69 i
0110 1010 106 6A j
0110 1011 107 6B k
0110 1100 108 6C l
0110 1101 109 6D m
0110 1110 110 6E n
0110 1111 111 6F o
0111 0000 112 70 p
0111 0001 113 71 q
0111 0010 114 72 r
0111 0011 115 73 s
0111 0100 116 74 t
0111 0101 117 75 u
0111 0110 118 76 v
0111 0111 119 77 w
0111 1000 120 78 x
0111 1001 121 79 y
0111 1010 122 7A z
0111 1011 123 7B {
0111 1100 124 7C |
0111 1101 125 7D }
0111 1110 126 7E ~

下表为 ascii 不可见字符表。

二进制 十进制 十六进制 缩写 可以显示的表示法 名称/意义
0000 0000 0 00 NUL ␀ 空字符(Null)
0000 0001 1 01 SOH ␁ 标题开始
0000 0010 2 02 STX ␂ 本文开始
0000 0011 3 03 ETX ␃ 本文结束
0000 0100 4 04 EOT ␄ 传输结束
0000 0101 5 05 ENQ ␅ 请求
0000 0110 6 06 ACK ␆ 确认回应
0000 0111 7 07 BEL ␇ 响铃
0000 1000 8 08 BS ␈ 退格
0000 1001 9 09 HT ␉ 水平定位符号
0000 1010 10 0A LF ␊ 换行键
0000 1011 11 0B VT ␋ 垂直定位符号
0000 1100 12 0C FF ␌ 换页键
0000 1101 13 0D CR ␍ 归位键
0000 1110 14 0E SO ␎ 取消变换(Shift out)
0000 1111 15 0F SI ␏ 启用变换(Shift in)
0001 0000 16 10 DLE ␐ 跳出数据通讯
0001 0001 17 11 DC1 ␑ 设备控制一(XON 启用软件速度控制)
0001 0010 18 12 DC2 ␒ 设备控制二
0001 0011 19 13 DC3 ␓ 设备控制三(XOFF 停用软件速度控制)
0001 0100 20 14 DC4 ␔ 设备控制四
0001 0101 21 15 NAK ␕ 确认失败回应
0001 0110 22 16 SYN ␖ 同步用暂停
0001 0111 23 17 ETB ␗ 区块传输结束
0001 1000 24 18 CAN ␘ 取消
0001 1001 25 19 EM ␙ 连接介质中断
0001 1010 26 1A SUB ␚ 替换
0001 1011 27 1B ESC ␛ 跳出
0001 1100 28 1C FS ␜ 文件分割符
0001 1101 29 1D GS ␝ 组群分隔符
0001 1110 30 1E RS ␞ 记录分隔符
0001 1111 31 1F US ␟ 单元分隔符
0111 1111 127 7F DEL ␡ 删除

本节重要知识点

会使用 base64 进行编解码。

清楚 base64 使用的场景。

点赞:0 分享

上一篇
python中time模块详解
下一篇
python中itertools模块详解
作者头像 作者名称 作者性别
韩俊

热门推荐

1 python如何实现向上取整
2 《Python编程从入门到实践》第3版 影响超250万读者[pdf]
3 Python3函数自定义和调用
4 Python序列化和反序列化
5 Python3迭代
6 python中collections库详解

评论列表

取消回复

    •  
      Login

      韩俊

      趁你现在还有时间,尽你自己最大的努力,努力做成你最想做的那件事,成为你最想成为的那种人,过着你最想过的那种生活。这个世界永远比你想的要更精彩,不要败给生活。

      退出登陆
      • 10358文章
      • 455评论
      • 80微语
  • 广告赞助

  • 二零二五年07月
    一二三四五六日
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
  • 分类

    • 网站模板源码
    • IT技术笔记
    • 好资源分享
    • 共享网络资源
  • 最新文章

      • 蛋糕跨年祝福语简短独特
        • 元旦祝福语简短儿童
          • 跨年家人聚会祝福语简短
            • 兄弟生日简短祝福语常用
              • 求婚父母祝福语简短精辟
                • 幽默俏皮的祝福语简短
                  • 拍摄国庆祝福语简短
                    • 夏天防暑祝福语大全简短
  • 热门文章

    • 酷狗音乐VIP账号 酷狗音乐会员账号共享2017.01.29更新
    • 芒果tv vip会员账号 芒果tv会员账号共享2017.01.29更新
    • 爱奇艺vip账号 爱奇艺/PPS会员账号共享2016.12.12更新
    • 优酷/土豆vip会员账号 优酷会员账号共享2017.01.29更新
    • 活动:免费获得爱奇艺VIP/PPS会员账号50天以上的使用权!
    • 酷我音乐VIP账号 酷我音乐会员账号共享2016.12.31更新
    • 暴风影音会员账号 暴风影音会员账号共享2016.12.31更新
    • m1905会员账号 m1905会员账号共享2016.10.21更新
  • 最新评论

    • https://www.vipshare8.com/content/templates/meta/Static/images/tx/10.jpg

      你丫的 文章写得太好了 支持下!![F3...

    • https://www.vipshare8.com/content/templates/meta/Static/images/avatar.jpg

      很棒!刚在某网站看到这个,很欣赏,可惜下...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=3861064027

      呃呃呃 oooo

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      回复了111:根据激活的时间有一年的有效期!

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=792480561

      到2025就到期了吗?

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      [blockquote]打卡时间:16:...

    • https://www.vipshare8.com/content/templates/meta/Static/images/tx/7.jpg

      俊哥,想借用迅雷一用!但需要手机验证!看...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=3293901900

      感谢大大的分享

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      回复了好奥v:如果没有解析成功,可以切换接口...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=131241242441

      现在视频解析网站怎么用不了啦?

  • 网站统计 I 当前在线:959人

    • 本站管理:1位
    • 用户总数:593位
    • 置顶文章:2篇
    • 日志总数:10358篇
    • 微语总数:80条
    • 评论总数:455条
    • 标签总数:83条
    • 页面总数:8页
    • 分类总数:14个
    • 链接总数:16条
    • 运行天数:3730天
    • 最后更新:7月15日
    • 登录
    • 注册
    • 找回
    Copyright © 2025vip共享吧网站地图 网站备案豫ICP备19004194号-1

    免责声明:本站资源仅供用于学习和交流,本站部分素材内容来源于网络,如有侵权/投稿等,请及时联系站长.

    • 首页
    • 秒懂百科 秒懂百科
    • 搜索
    • 史上今日

    大家都在搜

    • 乐视视频
    • 喜马拉雅FM会员账号
    • 秒懂百科
    • 网站源码
    • 华数tv会员账号分享
    • 咪咕会员账号
    • 酷狗会员账号共享
    • 百度云会员账号共享
    • 威客平台
    • 手机赚钱软件
    • 爱奇艺会员账号共享
    • 好省
    • 咪咕会员账号共享
    • 飞卢小说vip账号共享
    • 飞卢小说会员账号
    • 哔哩哔哩vip会员账号
    • 
    • 