尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

编码问题(字符串与字节)

编码问题(字符串与字节) Python 字符串、字节、编码与 Base64 知识总结大家好我是小马不起床。编码是爬虫与后端开发中最容易被忽视、却又最容易引发疑难问题的一环乱码、UnicodeDecodeError、Base64 还原失败根源几乎都在于对str与bytes的边界认识不清。本文系统梳理 Python 中str、bytes、encode()、decode()、UTF-8、GBK 与 Base64 的核心概念及标准转换流程篇幅不长但值得彻底吃透。目录Python 中的两种核心对象UTF-8 / GBK 的本质encode()字符串转字节decode()字节转字符串encode 与 decode 的方向性文件读写的本质GBK 转 UTF-8UTF-8 转 GBK乱码的本质Base64 的本质Base64 与 UTF-8 / GBK 的区别字符串转 Base64Base64 还原为字符串常见转换流程汇总核心规则速查一句话总结1. Python 中的两种核心对象Python 中首先需要严格区分两类对象str 字符串面向展示的文本 bytes 字节文件 / 网络 / 二进制数据的底层形态示例text你好# strdatabhello# bytes关键结论文件、网络传输、图片、压缩包、加密结果其底层形态均为 bytes。 Python 中可直接进行文本处理的对象是 str。2. UTF-8 / GBK 的本质UTF-8、GBK 属于字符编码。其职责是解决字符串 str 与字节 bytes 之间的双向转换规则同一字符串采用不同编码将得到不同的 bytes。例如你好.encode(utf-8) → E4 BD A0 E5 A5 BD 你好.encode(gbk) → C4 E3 BA C3即字符串内容相同底层存储字节可能完全不同。3. encode()字符串转字节encode()的定义str.encode(编码) 将字符串按指定编码转换为 bytes示例代码text你好utf8_bytestext.encode(utf-8)gbk_bytestext.encode(gbk)print(utf8_bytes)print(gbk_bytes)输出结果b\xe4\xbd\xa0\xe5\xa5\xbdb\xc4\xe3\xba\xc3对应关系你好 --encode(utf-8)-- UTF-8 bytes 你好 --encode(gbk)---- GBK bytes4. decode()字节转字符串decode()的定义bytes.decode(编码) 将 bytes 按指定编码还原为 str示例代码utf8_datab\xe4\xbd\xa0\xe5\xa5\xbdtextutf8_data.decode(utf-8)print(text)输出你好对应关系UTF-8 bytes --decode(utf-8)-- 你好 GBK bytes --decode(gbk)---- 你好5. encode 与 decode 的方向性正确写法你好.encode(utf-8)# str - bytesb....decode(utf-8)# bytes - str错误写法你好.decode(utf-8)# 错误str 类型不存在 decode 方法b....encode(utf-8)# 通常错误bytes 应执行 decode方向规则encode编码str → bytes decode解码bytes → str6. 文件读写的本质6.1 读文件代码withopen(a.txt,r,encodingutf-8)asf:textf.read()其本质是文件 bytes → decode(utf-8) → str若文件实际以 GBK 存储却声明按 UTF-8 读取将出现乱码或直接抛出异常。6.2 写文件代码withopen(a.txt,w,encodingutf-8)asf:f.write(你好)其本质是str → encode(utf-8) → 文件 bytes若改写为 GBKwithopen(a.txt,w,encodinggbk)asf:f.write(你好)其本质是str → encode(gbk) → 文件 bytes由此可推知open()中的encoding参数决定的是字节与字符串之间的转换规则。7. GBK 转 UTF-8GBK 转 UTF-8 并非直接改写 bytes而必须经由 str 中转GBK bytes → 按 GBK 解码为 str → 再按 UTF-8 编码为 bytes示例代码gbk_bytesb\xc4\xe3\xba\xc3textgbk_bytes.decode(gbk)utf8_bytestext.encode(utf-8)print(text)print(utf8_bytes)转换流程C4 E3 BA C3 ↓ decode(gbk) 你好 ↓ encode(utf-8) E4 BD A0 E5 A5 BD8. UTF-8 转 GBK示例代码utf8_bytesb\xe4\xbd\xa0\xe5\xa5\xbdtextutf8_bytes.decode(utf-8)gbk_bytestext.encode(gbk)print(text)print(gbk_bytes)转换流程E4 BD A0 E5 A5 BD ↓ decode(utf-8) 你好 ↓ encode(gbk) C4 E3 BA C3需要注意若字符串中包含 emoji 或 GBK 字符集未收录的特殊符号 encode(gbk) 将抛出 UnicodeEncodeError。9. 乱码的本质乱码的根本原因以错误的编码对 bytes 执行 decode例如gbk_bytesb\xc4\xe3\xba\xc3textgbk_bytes.decode(utf-8)即GBK bytes 被错误地按 UTF-8 规则解码由此产生的典型现象UnicodeDecodeError 乱码字符因此排查乱码问题时应优先回答两个问题这串 bytes 的原始编码是什么 当前用于 decode 的编码是什么二者不一致即为乱码根源。10. Base64 的本质Base64 是将任意 bytes 转换为可见文本的编码方式。它不属于 UTF-8、GBK 一类的字符编码。Base64 解决的问题是二进制 bytes 不便于直接嵌入 JSON、URL、邮件、文本字段 因此先将 bytes 转换为一串安全的可见字符。示例代码importbase64 databhellob64base64.b64encode(data)print(b64)输出baGVsbG8含义bhello → Base64 → baGVsbG811. Base64 与 UTF-8 / GBK 的区别对比维度UTF-8 / GBKBase64类型字符编码二进制到文本的编码作用str ↔ bytesbytes ↔ 可见文本输入对象字符串文本任意 bytes是否承载语言文字是否常见用途文件读写、接口文本、中文编码图片、文件、token、加密结果传输是否属于加密否否体积变化不确定通常增大约 1/3核心区别UTF-8 / GBK解决文字如何转换为字节 Base64解决字节如何转换为可见文本12. 字符串转 Base64字符串不能直接进行 Base64 编码必须先转换为 bytes。示例代码importbase64 text你好datatext.encode(utf-8)# str - bytesb64base64.b64encode(data)# bytes - Base64 bytesprint(b64)输出b5L2g5aW9完整流程你好 ↓ encode(utf-8) UTF-8 bytes ↓ base64.b64encode() Base64 bytes: b5L2g5aW9如需得到普通字符串形态b64_textb64.decode(ascii)print(b64_text)输出5L2g5aW913. Base64 还原为字符串示例代码importbase64 b64b5L2g5aW9database64.b64decode(b64)# Base64 - 原始 bytestextdata.decode(utf-8)# bytes - strprint(text)输出你好完整流程Base64 文本 5L2g5aW9 ↓ base64.b64decode() UTF-8 bytes ↓ decode(utf-8) 你好需要注意Base64 解码得到的是原始 bytes。 这些 bytes 应以 UTF-8、GBK 还是其他编码执行 decode 取决于其最初采用何种编码 encode。14. 常见转换流程汇总14.1 文本写入文件str → encode(utf-8) → bytes → 写入文件14.2 从文件读取文本文件 bytes → decode(utf-8) → str14.3 GBK 转 UTF-8GBK bytes → decode(gbk) → str → encode(utf-8) → UTF-8 bytes14.4 UTF-8 转 GBKUTF-8 bytes → decode(utf-8) → str → encode(gbk) → GBK bytes14.5 字符串转 Base64str → encode(utf-8) → bytes → base64.b64encode() → Base64 bytes / Base64 文本14.6 Base64 还原字符串Base64 文本 → base64.b64decode() → 原始 bytes → decode(utf-8) → str15. 核心规则速查str 转 bytesencode bytes 转 strdecode decode 依据原始 bytes 的编码 encode 依据期望输出的编码 UTF-8 / GBKstr ↔ bytes Base64bytes ↔ 可见文本 Base64 不是加密仅是编码。 任何人取得 Base64 字符串均可直接解码还原原始 bytes 因此敏感数据严禁仅以 Base64 代替加密存储或传输。16. 一句话总结字符编码解决文本与字节之间的转换 Base64 解决字节与可见文本之间的转换。搞清这两条转换链路乱码和 Base64 相关的绝大多数问题就有了排查方向。如果这篇总结对你有帮助欢迎点赞、收藏、转发有问题也欢迎在评论区交流。我是小马不起床我们下期见。
返回列表