Python ZIpFile 解惑:GBK 编码与乱码现象
文章目录
- 参考
- 描述
- 铺垫
- 乱码现象
- 编码与解码
- 编码
- 解码
- 字符集
- Unicode 字符集
- UTF-8
- CP437
- Zip 文件与 CP437 编码
- GB2312
- GB2012
- GBK
- 单字节编码与多字节编码
- 溯源
- 通用标志位与语言编码标志
- ZipFile 所支持的两种编码方式
- GBK 编码与 Zip 应用
- 乱码现象产生的原因
- 解决
参考
项目 | 描述 |
---|---|
维基百科 | ZIP 格式 |
Python 官方文档 | zipfile - 使用ZIP存档 |
搜索引擎 | Google、Bing |
Zip 文件格式规范 | APPNOTE.TXT |
维基百科 | 首页 |
百度百科 | 首页 |
描述
项目 | 描述 |
---|---|
Python | 3.10.6 |
操作系统 | Windows 10 专业版(x86-64) |
压缩软件 | 360压缩(4.0.0.1460) |
铺垫
本部分内容为铺垫内容,除 “乱码现象” 为必看内容外,其余均为选看内容。如本部分内容已观看完毕,请移步至 “溯源” 部分继续观看。
乱码现象
在使用国内主流的 Zip 压缩软件将文件进行压缩后,若使用 Python 模块 ZipFile 对 Zip 文件中被存储文件的名称进行提取,往往会产生乱码现象。对此,请参考如下示例:
import zipfile# 月亮与六便士.zip 文件是使用 360压缩将
# 月亮与六便士.txt 文件 进行压缩后得到的产物。
ZIPPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮与六便士.zip'# 以只读方式打开 Zip 文件
with zipfile.ZipFile(ZIPPATH) as fz:# 迭代名称列表,输出 Zip 文件中所有文件的名称for name in fz.namelist():print(name)
执行效果
╘┬┴┴╙δ┴∙▒π╩┐.txt
编码与解码
编码
编码通常是为了将文本进行存储、传输或处理,因为 计算机只能处理数字。常见的编码方式包括 ASCII、Unicode、UTF-8 等。
解码
解码是指将已经被编码的数字或数字序列转换回原始的字符或文本的过程。解码的过程是编码的逆过程,通常需要使用与编码方式相同的规则和算法来进行解码。
字符集
在计算机中,字符集(Character Set)是由一系列字符组成的集合,每个字符都对应一个唯一的编码。常见的字符集包括 ASCII、Unicode 等。
Unicode 字符集
Unicode 字符集中的一种,它包含了全球所有语言中的字符,并且可以进行扩展,支持更多的字符。 Unicode 字符集目前已经超过了 100,000 个字符,其中包括了各种字母、数字、标点符号、符号、表情符号等。
Unicode 的编码方式有多种,其中比较常见的是 UTF-8、UTF-16 和 UTF-32。不同的编码方式使用不同的位数来表示一个字符,UTF-8 使用 1 到 4 个字节来表示一个字符,UTF-16 使用 2 或 4 个字节来表示一个字符,UTF-32 使用 4 个字节来表示一个字符。
Unicode 字符集的出现解决了多语言字符集的混乱问题,使得各个语言之间的交流和互动更加方便和自然。 在计算机领域,Unicode 的广泛使用也使得字符编码的处理更加便捷和标准化。
UTF-8
UTF-8(Unicode Transformation Format-8) 是一种 可变长度 的字符编码方式,它是 Unicode 字符集 中的一种。
UTF-8 是一种可变长度的编码方式,可以用来表示 Unicode 中的任何字符。UTF-8 编码方式使用 1 到 4 个字节来表示一个字符,较少使用的字符使用数量较多的字节,而常用的字符则使用数量较少的字节,以便节约存储空间。
除了 UTF-8 之外,Unicode 还存在其他的编码方式,如 UTF-16 和 UTF-32,但是在实际应用中,UTF-8 是最为广泛使用的编码方式之一。
CP437
CP437 是字符集中的一种,也称为 IBM PC 字符集 或 DOS 字符集。它最初是为 IBM PC 设计的,用于在早期的个人计算机上显示字符和符号。CP437 包含了 256 个字符,包括了字母、数字、标点符号、符号以及各种特殊符号等。
CP437 的编码方式是一个字节表示一个字符,它使用了 ASCII 编码中未被使用的 128 个字符位置来表示新的字符和符号。因此,CP437 可以被认为是 ASCII 字符集的扩展版本。
CP437 主要用于早期的个人计算机系统,例如 IBM PC 和 DOS 系统。虽然它已经被现代的 Unicode 字符集所取代,但是在一些旧的系统和应用中,仍然会使用 CP437 编码方式。
Zip 文件与 CP437 编码
ZIP 文件在历史上并没有指定元数据信息的编码方式,但强烈推荐使用 CP437 编码(原始的 IBM PC 编码)以实现互操作性。这是因为 CP437 编码是一个非常基础的编码方式,几乎所有计算机系统都能够识别它。
当然,现代的 ZIP 实现已经支持使用 UTF-8 编码来存储文件名和注释信息。但是,由于历史原因和兼容性问题,一些旧的 ZIP 工具可能仍然只支持使用 CP437 编码。因此,为了确保 ZIP 文件的兼容性,强烈建议在创建 ZIP 文件时使用 CP437 进行编码。如果需要使用其他编码方式进行解码,则应将其转换为 CP437 编码再对其进行解码操作。
GB2312
GB2312 是中国国家标准中的一种字符集编码方式,它最初于 1980 年发布,是为了在计算机系统中表示汉字而开发的。GB2312 字符集中包含了大约 7,000 个常用汉字和约 700 个非汉字字符,例如数字、字母和符号等。
GB2312 使用双字节编码方式,每个汉字使用两个字节来表示,而每个非汉字字符(如数字、字母和符号)使用一个字节来表示。使用 GB2312 编码方式的文件可以在大多数中文操作系统和应用程序中正确显示汉字和其他字符。
GB2012
GB2012(GB/T 2312-2017)是 GB2312 字符集的升级版,与 GBK 有一些类似之处,它也使用双字节编码,每个汉字使用 2 个字节来表示,而每个非汉字字符使用一个字节表示。GB2012 扩展了 GB2312 中的字符集,增加了一些生僻汉字和其他字符。与 GBK 不同的是,GB2012 中新增的字符主要来自于香港和台湾地区的繁体中文字符集,因此在某些情况下,GB2012 可能比 GBK 更适合表示繁体中文。
GBK
GBK 是在 GB2312 字符集的基础上进行扩展的编码方式,它包含了 GB2312 中的所有汉字,并扩展了更多的汉字和其他字符,使得它能够表示包括繁体中文在内的大部分东亚语言中的字符。GBK 使用双字节编码,每个汉字使用 2 个字节来表示,而每个非汉字字符(如英文、数字和符号)使用一个字节表示。GBK 是在中国大陆广泛使用的字符集编码方式,也是 Windows 操作系统中默认的中文字符集编码方式之一。
单字节编码与多字节编码
单字节编码是一种字符编码方式,其中 每个字符使用一个固定的字节表示。例如,在 ASCII 编码中,每个字符都用一个字节表示,字节的值对应于该字符在 ASCII 表中的位置。
多字节编码是另一种字符编码方式,其中每个字符使用多个字节来表示。 例如,在 UTF-8 编码中,一个字符可以由 1 到 4 个字节组成,具体的字节数量取决于字符所在的 Unicode 编码范围。
单字节编码在存储和传输文本数据时通常比多字节编码更简单、更高效,因为每个字符只需要一个固定大小的字节。然而,由于单字节编码只能表示有限的字符集,不能满足全球化和多语言支持的需求,因此多字节编码在现代计算机系统中得到了广泛的应用。
溯源
通用标志位与语言编码标志
通用位标志 (General Purpose Bit Flag) 是一组用于 ZIP 文件头部的二进制位标记,大小为两个字节(即 16 bits),用于指示 ZIP 文件中的各种信息,例如文件是否使用了压缩算法,是否加密等。EFS (Language encoding flag) 是其中的一位标记,即第 11 位,用于指示 ZIP 文件中的文件名和注释信息采用的字符编码方式是否为 UTF-8。
当 ZIP 文件中的文件名和注释信息 都 采用 UTF-8 编码时,可以设置 EFS 标志来表示这一信息(据说,可以提高与早期 Zip 文件的兼容性)。这样,在读取 ZIP 文件时,程序就能够正确地解析文件名和注释信息的编码方式,从而正常地显示这些信息 (在 ZipFile 中,获取文件注释信息d的结果为一个字节串,你需要自己对它们进行解码来获取注释信息)。
ZipFile 所支持的两种编码方式
ZipFile 模块仅使用 CP437 及 UTF-8 编码对文件路径及注释进行解码。ZipFile 模块首先将判断 Zip 内存储的文件路径是否是使用 UTF-8 进行编码的。若是,则使用 UTF-8 对其进行解码;若不是,则使用 CP437 对其进行解码。关于这点,我们可以从 ZipFile 模块的源码中窥见一斑。
if flags & 0x800:# UTF-8 file names extensionfilename = filename.decode('utf-8')
else:# Historical ZIP filename encodingfilename = filename.decode('cp437')
其中:
flags 代表Zip文件中某个文件的通用标志位。在这个 if-else 语句 中,程序会首先检查该文件的通用标志位的 第 11 位 是否为 1(通过将 flags 与 0x800 进行按位与操作来达成此目标),如果为 1 则表示该文件的文件名使用了 UTF-8 编码,需要使用 UTF-8 进行解码;否则表示该文件的文件名使用了历史的 ZIP 文件名编码(即CP437),需要使用 CP437 进行解码。
GBK 编码与 Zip 应用
ZIP 文件格式本身并没有规定文件路径与注释信息必须使用哪种编码方式进行存储。如果压缩软件开发者不进行特别的处理,可能会采用默认的编码方式,例如在中国地区,许多压缩软件默认使用 GBK 编码方式来处理文件名。
在国内,一些压缩软件将文件路径及注释使用GBK编码进行处理,以下是一些常见的压缩软件:
-
360压缩
-
傲游压缩
-
金山压缩
乱码现象产生的原因
在使用国内主流的压缩软件将文件压缩为 Zip 文件时,会使用 GBK 对文件路径及 Zip 文件的注释信息进行编码。而 ZipFile 模块在检测出该 Zip 文件未设置 语言编码标志 后,使用 CP437 对文件路径进行解码,于是就得到了我们所看到的乱码现象。
对 “乱码现象” 中存在的编码与解码操作进行模拟
filename = '月亮与六便士.txt'# 将 filename 进行 GBK 编码
gbk_filename = filename.encode('GBK')
print(gbk_filename)# 使用 CP437 对使用 GBK 编码后的结果进行解码操作
result = gbk_filename.decode('CP437')
print(result)
执行效果
使用 CP437 解码使用 GBK 编码的字符串得到的结果与本文开头所介绍的乱码现象中出现的乱码完全一致。
b'\xd4\xc2\xc1\xc1\xd3\xeb\xc1\xf9\xb1\xe3\xca\xbf.txt'
╘┬┴┴╙δ┴∙▒π╩┐.txt
解决
我们得到的乱码文字是由于将 GBK 编码的字节串使用 CP437 对其进行解码后得到的,那么我们仅需要将乱码文字再次编码为 CP437 并对其进行 GBK 解码操作就能够得到正确的文件名称了。对此,我们对代码进行如下改造:
import zipfile# 月亮与六便士.zip 文件是使用 360压缩将
# 月亮与六便士.txt 文件 进行压缩后得到的产物。
ZIPPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮与六便士.zip'# 以只读方式打开 Zip 文件
with zipfile.ZipFile(ZIPPATH) as fz:# 迭代名称列表,输出 Zip 文件中所有文件的名称for name in fz.namelist():# 对文件名称进行编码和解码操作result = name.encode('CP437').decode('GBK')print(result)
执行效果
月亮与六便士.txt
相关文章:

Python ZIpFile 解惑:GBK 编码与乱码现象
文章目录 参考描述铺垫乱码现象编码与解码编码解码 字符集Unicode 字符集UTF-8CP437Zip 文件与 CP437 编码 GB2312GB2012GBK 单字节编码与多字节编码 溯源通用标志位与语言编码标志ZipFile 所支持的两种编码方式GBK 编码与 Zip 应用乱码现象产生的原因 解决 参考 项目描述维基…...

【LeetCode】213. 打家劫舍 II
213. 打家劫舍 II(中等) 思路 这道题是 198.打家劫舍 的拓展版,区别在于:本题的房间是环形排列,而198.题中的房间是单排排列。 将房间环形排列,意味着第一间房间和最后一间房间不能同时盗窃,因…...

从初识RabbitMQ到安装了解
一、同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应。 异步通讯:就像发邮件,不需要马上回复。 两种方式各有优劣,打电话可以立即得到响应,但是你却不…...

MySQL(六)-字符串函数的使用解析
字符串函数的使用解析 1 计算字符串字符数的函数和字符串长的函数2 合并字符串函数 CONCAT(s1,s2,...)、CONCAT_WS(xs1,s2,...)3 替换字符串函数INSERT(s1,x,len,s2)4 字母大小写转换函数5 获取指定长度的字符串的函数LEFT(s,n)和RIGHT(s,n)6 填充字符串的函数 LPAD(s1,len,s2)…...

Zookeeper集群搭建
搭建Zookeeper集群 1.1 搭建要求 真实的集群是需要部署在不同的服务器上的,但是在我们测试时同时启动很多个虚拟机内存会吃不消,所以我们通常会搭建伪集群,也就是把所有的服务都搭建在一台虚拟机上,用端口进行区分。 我们这里要…...

【计算机视觉 | 目标检测】OVD:Open-Vocabulary Object Detection 论文工作总结(共八篇)
文章目录 一、2D open-vocabulary object detection的发展和研究现状二、基于大规模外部图像数据集2.1 OVR-CNN:Open-Vocabulary Object Detection Using Captions,CVPR 20212.2 Open Vocabulary Object Detection with Pseudo Bounding-Box Labels&…...

C++入门基础知识[博客园长期更新......]
0.博客园链接 博客的最新内容都在博客园当中,所有内容均为原创(博客园、CSDN同步更新)。 C知识点集合 1.命名空间 在往后的C编程中,将会存在大量的变量和函数,因为有大量的变量和函数,所以C的库会非常多。那么在C语言编程中&a…...

( “树” 之 BST) 501. 二叉搜索树中的众数 ——【Leetcode每日一题】
二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。 二叉查找树中序遍历有序。 ❓501. 二叉搜索树中的众数 难度:简单 给你一个含重复值的二叉搜索树(BST)的根节点 root…...

openharmony内核中不一样的双向链表
不一样的双向链表 链表初识别遍历双向链表参考链接 链表初识别 最近看openharmony的内核源码时看到一个有意思的双向链表,结构如下 typedef struct LOS_DL_LIST{struct LOS_DL_LIST *pstPrev; //前驱节点struct LOS_DL_LIST *pstNext; //后继节点 }LOS_DL_LIST;不…...

大文件删除不在回收站里怎么找回
在日常办公中,总会有一些新的文件产生,和用完后的文件清理掉。有时候不小心误删文件也是常有的事。但如果大文件删除不在回收站里怎么找回呢?遇到的小伙伴们请不要别急,只要按照下面的方法做就行了。 正常情况下删除会进入到回收站中&#x…...

Ubuntu22.04部署Pytorch2.0深度学习环境
文章目录 安装Anaconda创建新环境安装Pytorch2.0安装VS CodeUbuntu下实时查看GPU状态的方法小实验:Ubuntu、Windows10下GPU训练速度对比 Ubuntu安装完显卡驱动、CUDA和cudnn后,下面部署深度学习环境。 (安装Ubuntu系统、显卡驱动、CUDA和cudn…...

php的面试集结(会持续更新)
PHP 高级工程面试题汇总 php面试 1.大型的分页查询 发现当表中有很多上万条数据时,越后的数据用limit分页显示就越慢(>2秒),可能是mysql的特性所致。所以花了点时间总结实现了更优解决方案,最终实现毫秒级响应。…...

谁在成为产业经济发展的推车人?
区域发展的新蓝图中,京东云能做什么?它的角色是什么?这个问题背后,隐藏的不仅是京东云自身的能力和价值,更是其作为中国互联网云厂商的代表之一,对“技术产业”的新论证。 作者|皮爷 出品|产业家 关于云…...

上海无纺布制造商【盈兹】申请纳斯达克IPO上市,募资1100万美元
来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,来自上海的无纺布制造商【盈兹】,近期已向美国证券交易委员会(SEC)提交招股书,申请在纳斯达克IPO上市,股票代码为(ETZ&#…...

Build an SAP Fiori App(一)后面更新中
1.登录 SAP BTP Trial 地址: https://account.hanatrial.ondemand.com 流程可以参考 点击 serviced marketplace 搜索studio 点击创建 点击创建,点击view subscription 点击go to application 创建完成后 添加新链接 Field Value Name ES5 - if you’…...

关于GNSS技术介绍(二)
在上期文章中,我们介绍了GNSS技术的发展历程、原理,并对不同类型的定位技术进行了介绍,在本期文章中我们将继续讨论GNSS的优点与应用及其测试方法和解决方案。 GNSS的优点与应用 目前GNSS技术已经成为日常生活不可或缺的一部分,几…...

拿到新的服务器必做的五件事(详细流程,开发必看)
目录 1. 配置免密登录 基本用法 远程登录服务器: 第一次登录时会提示: 配置文件 创建文件 然后在文件中输入: 密钥登录 创建密钥: 2.部署nginx 一、前提条件 二、安装 Nginx 3.配置python虚拟环境 1.安装虚拟环境 …...

主机防病毒攻略之勒索病毒
勒索病毒并不是某一个病毒,而是一类病毒的统称,主要以邮件、程序、木马、网页挂马的形式进行传播,利用各种加密算法对文件进行加密,被感染者一般无法解密,必须拿到解密的私钥才有可能破解。 已知最早的勒索软件出现于 …...

Win10系统重装过程(一键装机)
相信不少小伙伴都有刷机重装系统的过程,那种镜像,up盘,压缩包等多个复杂过程也折磨的大伙不堪重负,因此本期带来简易版一键装机相应操作。 下载地址: 小心点击下方链接,点击即下载(3.66GB&…...

查询优化之单表查询
建表 CREATE TABLE IF NOT EXISTS article ( id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, author_id INT(10) UNSIGNED NOT NULL, category_id INT(10) UNSIGNED NOT NULL, views INT(10) UNSIGNED NOT NULL, comments INT(10) UNSIGNED NOT NULL, title VARBI…...

ChatGPT写小论文
ChatGPT写小论文 只是个人对写小论文心得?从知乎,知网自己总结的,有问题,可以留个言我改一下 文章目录 ChatGPT写小论文-1.写论文模仿实战(狗头)0.论文组成1.好论文前提:2.标题3.摘要4.关键词5.概述6.实验数据、公式或者设计7.结论,思考8.参考文献 0.模仿1.喂大纲…...

公共资源包发布流程详解
文章目录 公有包发布并使用npm安装git仓库协议创建及使用 npm 私有包创建及使用 group npm 私有包私有仓账密存放位置 当公司各个系统都需要使用特定的业务模块时,这时候将代码抽离,发布到 npm 上,供下载安装使用,是个比较好的方案…...

设计模式简谈
设计模式是我们软件架构开发中不可缺失的一部分,通过学习设计模式,我们可以更好理解的代码的结构和层次。 设计原则 设计原则是早于设计方法出现的,所以的设计原则都要依赖于设计方法。这里主要有八个设计原则。 推荐一个零声学院免费教程&…...

day35—选择题
文章目录 1.把逻辑地址转换程物理地址称为(B)2.在Unix系统中,处于(C)状态的进程最容易被执行3. 进程的控制信息和描述信息存放在(B)4.当系统发生抖动(thrashing)时,可以采取的有效措…...

mybatis的<foreach>标签使用
记录:419 场景:使用MyBatis的<foreach></foreach>标签的循环遍历List类型的入参。使用collection属性指定List,item指定List中存放的对象,separator指定分割符号,open指定开始字符,close指定结…...

干货 | 被抑郁情绪所困扰?来了解CBT吧!
Hello,大家好! 这里是 壹脑云科研圈 ,我是 喵君姐姐~ 我们的情绪就像是一组正弦波,有情绪很高涨的时刻,也会有情绪低落的瞬间,也会有情绪平稳的时候。 这种情绪上的变化非常正常,也正是因为这…...

每日一个小技巧:1招教你手机消除笔怎么用
在日常生活中,我们经常需要在手机上进行编辑和涂改,但是由于各种原因,我们可能会做出错误或者不满意的修改。这时候,消除笔就派上用场了。消除笔可以帮助我们在不影响其他内容的前提下,对错误或者不满意的修改进行撤销…...

4月26号软件更新资讯合集....
Tpflow V7.0.2,PHP 工作流引擎新版发布 欢迎使用 Tpflow V7.0.1 工作流引擎 TpFlow 工作流引擎是一套规范化的流程管理系统,基于业务而驱动系统生命力的一套引擎。彻底释放整个信息管理系统的的活力,让系统更具可用性,智能应用型…...

尚硅谷大数据项目【电商数仓5.0】学习笔记
尚硅谷大数据项目【电商数仓5.0】学习笔记 大数据学习基础 基础shell编程:大数据之基础shell 集群快速安装教程:大数据集群快速安装教程 注:如果您已经有大数据学习基础,可以通过上面教程快速搭建学习环境,如果您没…...

vue3配置router路由并实现页面跳转
1、安装vue-router 用vue3需要安装版本4.0以上的vue-router,安装命令: npm install vue-routernext --savevue2尽量安装4.0以下版本,安装命令: npm i vue-router3.1.3在package.json中可以查看vue-router版本号: 2、…...