一、引言
分享知识+推广我的Python书。
上次本号分享了用Python把zip格式的压缩文件解压缩的三种方法:
① 用shutil 标准库解压缩
② 用unzip.exe以命令行方式解压缩
③ 用zipfile标准库解压缩
具体见《一文在手,解压无忧:说说用Python解压zip文件那些事儿》。
上次分享之后,小编发现两个问题:
带特殊密码的zip压缩文件无法用上述三种方法解压缩;
用AES算法加密的zip压缩文件无法用上述三种方法解压缩。
本文将探讨这两个问题。
《Python程序设计(基于计算思维和新文科建设)》,ISBN:9787121435577,胡凤国,电子工业出版社,2022年6月。本书是电子工业出版社在国内较早采用纸质版+电子版的创新图书发行模式的第一次尝试。本书是这套创新图书的纸质版部分,与之内容互补的电子版图书将稍后出版。基础篇介绍Python程序设计的入门知识,共12章,包括:⑵ Python软件的安装和Python程序运行;⑶ Python的基本概念(对象、数据类型、表达式、内置函数);排错篇总结初学者常遇到的错误并介绍程序调试方法,包含2章:与本书内容互补的电子版图书包含文本篇和应用篇两部分:文本篇:介绍字符集、编码和文本文件读写的知识,包含了对国家规范《通用规范汉字表》8105个汉字当中难以输入和难以显示的汉字的处理。应用篇:介绍Word、Excel、PPT、PDF、图片等常用办公文件的处理,是大家提高办公和科研效率的好帮手。本书配套有详细的PPT和教学大纲,还有全部例题的程序代码和绝大部分思考题的程序代码。本书配套PPT里面还加入了配套电子版图书中的部分内容,比如字符集和编码,不同编码的文本文件的读写,Word、Excel、PPT、PDF等一些常用办公文件的读写。1、大学文科生, 可选本书当Python教材或自学Python的参考书。2、大学理工科学生, 可选本书当自学Python的参考书。可拿本书当工具书,本书的配套程序会为您节省效率,在当前大数据和新文科的背景下,本书可以为相关领域的量化研究提供技术支持。本书配套的电子版图书中的编码和文本处理知识也可以作为理工科教师和科研人员处理文本数据的参考资料之一,毕竟专门开辟章节介绍国家标准《通用规范汉字表》汉字处理的程序设计图书并不多见。
本书有专门的海龟画图章节,有大量的有趣数学题目,可以培养学生的计算思维,适合对编程感兴趣的中小学生阅读,也适合打算让娃参加编程辅导班的家长朋友参考。本书在各大实体书店和网店均有销售。尤其在电子工业出版社天猫旗舰店销售火爆,月销量100+。京东、天猫、当当的购买渠道如下(可扫码直达购买页面)。我们先用 WinRAR 创建一个压缩文件,把 测试.txt 压缩成 测试.zip (在 测试.txt 的文件图标上点鼠标右键,选择“添加到压缩文件(A)…”)。
压缩文件格式选择“ZIP”,然后点击“确定”按钮。
此后就会得到 测试.zip 。我们双击这个文件,即可用 WinRAR 打开该压缩文件,看到这个压缩包是这样子的。

shutil标准库:

zipfile标准库:

unzip.exe软件(需配置环境变量):

上述三种解压缩方法都能把压缩包解开。不过,前两段代码解压缩得到的文件名是乱码:▓Γ╩╘.txt ,第三段代码解压出来的文件名正常。shutil标准库不能解压缩代码的zip压缩包,zipfile标准库和unzip.exe软件是可以的。下面创建一个带简单密码12345的压缩文件12345.zip。
在 12345.txt 的文件图标上点鼠标右键,选择“添加到压缩文件(A)…”),然后压缩文件格式选择“ZIP”,再点击“设置密码(P)…”按钮,如下图所示。
接下来,在弹出来的“输入密码”窗口中,输入密码12345,勾选“显示密码”就能看到输入的密码,我们还需要勾选“ZIP传统加密(z)”选项,如下图所示。

接下来,我们点击“确定”按钮关闭“输入密码”窗口,再点击“确定”按钮关闭“压缩文件名和 参数”窗口,就会得到带一个密码为12345的zip压缩文件12345.zip。
zipfile标准库:
unzip.exe软件:

【注意】需要说明的是,当12345.zip当中的12345txt的内容为空时,zipfile标准库解压缩出来的文件12345.txt大小依然是0字节,但unzip.exe解压缩得到的12345.txt内容不再为空,它的大小是12字节。小编想不出为什么这样,目前也解决不了这个问题,暂且存疑,这里只是把这种奇怪的现象记录一下。上面我们用WinRAR创建的是简单密码,而且勾选了“ZIP传统加密选项”,zipfile标准库和unzip.exe才能解压缩成功,如果换了复杂密码(比如带英文双引号),或者不勾选“ZIP传统加密(z)”选项,zipfile标准库和unzip.exe就不能成功解压缩。前者目前来看暂时无解,后者可以用pyzipper扩展库或WinRAR.exe来解决。四、关于包含特殊字符密码的zip压缩包无法解压的问题探讨
根据前面的介绍,我们知道对于带普通密码的zip压缩包,zipfile标准库和unzip.exe能轻松搞定。不过,对于复杂的密码,它们两个都搞不定。比如有个 test.zip ,它的密码是 1234"5,这个密码的4和5中间是一个半角双引号。这个包含特殊字符密码的zip压缩包是用WinRAR创建,加密方法是ZIP传统加密。

对于解压缩密码包含特殊字符的 test.zip,zipfile标准库无能为力,下面的程序居然不行。



unzip -o -P "1234"5" "test.zip"考虑到半角英文双引号在Windows的命令中是转义字符,小编在Windows命令行窗口中尝试了了很多命令:
unzip -o -P 1234"5 test.zip
unzip -o -P "1234"5" test.zip
unzip -o -P "1234\"5" test.zip
unzip -o -P "1234"""5" test.zip
unzip -o -P '1234"5' test.zip
上面的命令都以失败而告终,未能成功解压缩这个密码包含特殊字符的zip压缩包 test.zip 。
小编才疏学浅,没办法在Windows命令行窗口搞定合适的解压缩命令,就没办法在Python程序中把这个命令构造出来。
这个包含特殊字符的zip压缩包无法解压的问题暂且存疑,以后有时间的话再研究,这里只是把这种现象记录一下。
下面的操作,假设zip压缩包的密码均不包含特殊字符。
五、用pyzipper扩展库来解压缩AES算法加密的zip压缩包
本文前面提到,用WinRAR创建带密码的zip压缩包时,如果输入密码时不勾选“ZIP传统加密(z)”选项,得到的zip压缩文件用zipfile标准库和unzip.exe都不能成功解压缩。我们看个例子,创建一个文本文件 abcde.txt ,用 WinRAR 压缩成带密码 abcde 的 zip 文件 abcde.zip 。注意输入密码时不勾选“ZIP传统加密(z)”选项,如下图所示。

上面得到的 abcde.zip 用zipfile解压缩会失败。


skipping: abcde.txt unsupported compression method 99上网搜了一下关键词unsupported compression method 99,知道compression method 99 是指的AES(Adavanced Encryption Standard)加密算法 ,unzip.exe 不支持这种算法,所以无法解压缩。
又查了下一下资料,知道关于zip压缩文件有两种加密算法:1、Zip加密文件的加密算法通常包括AES和Zip 2.0传统加密(CRC32)算法。
2、用WinRAR可以创建加密的Zip压缩文件:
(1)设置密码时采取默认选项,也就是不勾选“ZIP传统加密(z)”,即可采用默认的AES算法对文件进行加密;
(2)设置密码时勾选“ZIP传统加密(z)”,即可采用Zip 2.0传统加密(CRC32)算法对文件进行加密。
3、Python标准库中的zipfile模块只支持Zip 2.0传统加密(CRC32)的zip文件,不能解密AES加密的Zip文件;
4、通过命令行运行unzip.exe,只能解密采用Zip 2.0传统加密(CRC32)算法加密的ZIP压缩包;
5、如果要解密AES加密的Zip文件,需要用到pyzipper扩展库,该库既可以解密采用AES算法加密的ZIP压缩文件,也可以解密采用Zip 2.0传统加密(CRC32)算法加密的ZIP压缩文件。
《zip加密文件的解密(Python版) 》
https://www.jianshu.com/p/dd915f27d1f4
根据这个资料,我们可以用pyzipper扩展库写出解压zip压缩文件的程序。

上述代码能够把前面提到的12345.zip成功解压缩。
上述代码能够把前面提到的abcde.zip成功解压缩。顺便说一下,对于包含特殊字符密码的zip压缩文件,pyzipper 扩展库也不能成功解压缩。六、用WinRAR.exe来解压缩AES算法加密的zip压缩包
我们也可以用Windows命令调用电脑上已安装的WinRAR.exe来解压缩zip压缩包,不管是没有密码的,还是普通密码的,不管是Zip 2.0传统加密(CRC32)算法加密的zip文件,还是AES算法加密的zip文件,只要不包含特殊字符,WinRAR.exe都能解压缩。只要我们安装了WinRAR,电脑上就会有WinRAR.exe,小编电脑上安装的是WinRAR 6.02。
上面这段代码可以成功解压缩 测试.zip ,如果没有出现测试.txt,可以把WinRAR.exe 所在的路径添加到环境变量Path当中,再来尝试。代码中的参数 -y 表示解压缩时如果存在着跟压缩包内同名的文件,直接覆盖不询问, -ibck 表示后台运行,如果不加这个参数,则会看到一个黑窗口一闪然后消失。
上面这段代码可以成功解压缩 Zip 2.0传统加密(CRC32)算法加密生成的12345.zip, 参数-P后面跟密码,不要有空格。

上面这段代码可以成功解压缩AES算法加密生成的abcde.zip。如果想把文件解压缩到指定路径,可以用如下的代码。

在指定路径事先存在的情况下,上述代码能够解压缩成功。不过,美中不足的是,如果指定路径不存在,解压缩失败,程序也不会提示出错。如果我们把 -y 参数去掉,就能够给出提示信息:

不过,这个提示信息是以弹出窗口的形式给出的,并不是在命令行窗口中以文字的形式给出。

遇到这种情况,我们还得手工点鼠标来干预。从这一点来看,虽然WinRAR.exe能够解压缩AES加密的zip压缩包,但它也不是理想的自动解压缩工具。顺便说一下,对于包含特殊字符密码的zip压缩文件,WinRAR.exe 也不能成功解压缩。欢迎跟图书《Python程序设计(基于计算思维和新文科建设)》的作者胡凤国老师进行交流,作者电邮:cuchufengguo@163.com ,也可以给公众号留言进行交流。欢迎关注微信公众号“语和言”,本公众号将不定期发布对本书Python知识点的解读和补充内容。
语和言公众号还有读者交流群,经常跟作者交流的读者朋友可以入群一起讨论问题。