祝各位读者朋友新春快乐!兔年一帆风顺,百毒不侵,万事如意。
一、引言
有的时候,我们需要把zip压缩包解压缩。此前本号曾经写过解压缩zip文件的一些文章,感兴趣的同学和读者朋友可以参考。目前网上的资料,判断zip压缩包的密码是否正确,多是用解压全部文件的办法来判定的:能解压成功就是正确的密码,不成功就是不正确的密码。今天本号讨论的是:如何在不解压zip文件的情况下如何判一个字符串是否正确的解压密码。环境:64位Win 10中文版 + 64位Python 3.7.6
《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的参考书。可拿本书当工具书,本书的配套程序会为您节省效率,在当前大数据和新文科的背景下,本书可以为相关领域的量化研究提供技术支持。本书配套的电子版图书中的编码和文本处理知识也可以作为理工科教师和科研人员处理文本数据的参考资料之一,毕竟专门开辟章节介绍国家标准《通用规范汉字表》汉字处理的程序设计图书并不多见。
本书有专门的海龟画图章节,有大量的有趣数学题目,可以培养学生的计算思维,适合对编程感兴趣的中小学生阅读,也适合打算让娃参加编程辅导班的家长朋友参考。本书在各大实体书店和网店均有销售。京东、天猫、当当的购买渠道如下(可扫码直达购买页面)。
三、全解压方式判断密码是否正确
假设有一个zip压缩包如下:
通常的解压方式是全解压:

上面的程序使用了扩展库pyzipper,需要用pip命令安装一下。为什么不用标准库zipfile呢?具体原因在文章
《一文在手,解压无忧:说说用Python解压zip文件那些事儿(2)》
里面进行了解释。
如果密码正确,就能解压成功,如果密码不正确,则程序运行会抛出异常,为了捕获这种异常,我们可以用try...except...结构。

虽然这样运行不会出错了,但如果压缩包很大,里面文件很多,解压缩还是非常浪费时间的。仅仅是为了判断一个密码是否正确,这样做是不是有点浪费资源?
四、澄清一种错误的判断密码方式
在打开zip文件之后,得到的zp对象有一个setpassword方法,可以预置zip压缩包的密码,setpassword之后,将来再extractall的时候,就不必再给定pwd参数。zp对象还有一个testzip方法,它的功能是读取每一个文件检验CRC(循环冗余校验码)是否有问题,如果有问题的话,就抛出异常,如果没问题,就返回None。如果我们给定正确的密码abcde,zp对象的testzip方法检验之后会返回None,如果我们给定几个错误的密码去检验,发现抛出异常。这我们可以猜想:可不可以用setpassword方法和testzip方法配合起来检验zip压缩包的密码是否正确呢?

本号主人曾经在长达一年的时间里对此方法深信不疑,一直用这种思路来判断zip压缩包的密码是否正确。直到有一天需要找回丢失的zip压缩包密码,也就是写下面这篇文章的时候:
我用上面的思路结合穷举法找zip压缩包 test_密码_abcde.zip 的密码,居然找到很多个密码,这怎么可能?正确的密码显然只能有一个,这就印证了上面的思路判断密码是否正确的方法根本不对。
我们居然发现,这四个字符串作为密码去测试都能测试成功。除了第一个abcde是真密码之外,其它都是伪密码。这样的伪密码还能找来很多个。
顺便说一下,不同的zip压缩包,即便真密码一样,但伪密码可能是不同的。所以,大家在自己电脑上测试程序时,伪密码要是跟我这里不一样,也是正常的,因为咱们的zip压缩包的内容可能是不一样的。
如果不是因为穷举法寻找zip压缩包的密码,我可能还会一直把这种方法当做一个“伟大”的发现,现在,这种方法自然是泡汤了。记录在此,给我自己也给大家提个醒,免得再有人会犯同样的错误。五、无需解压就能判断zip包密码是否正确的方法
我们知道,读取zip包得到的对象zp,除了有extractall方法可以解压全部文件之外,还有extract方法来解压单个文件。我们不需要解压全部文件,解压一个文件不就行了嘛?
问题是,一个zip压缩包中,既有加密码的文件,也有不加密码的文件,如何判断压缩包中的加密文件和未加密文件呢?这自然是有办法的。刨除掉未加密的文件之外,我们只需要从剩下的当中选一个,解压缩,如果解压缩成功,不就说明密码正确了嘛。问题是,如果不幸选了一个体积大的文件,那解压还得占时间占空间嘛。我们又两点改进:第二、用read方法代替extract方法,只读取不解压,可节省空间。


我们发现,只有真密码abcde测试成功,其它的各种假密码、伪密码都测试失败。
上面的程序没考虑极端情况,压缩包中就一个文件,而且文件体积很大,万一压缩包比内存还要大,这读取不就失败了嘛。一般情况下,我们遇到的文件不会这么奇葩,一旦发生了这种情况,我觉得可以出门直奔彩票站买买买了。
由于本号文章以辅助教学为主,笔者不建议自己的学生直接拿代码运行,而是建议在理解了思路之后自己敲代码来加深印象,所以本号一般不直接贴代码。如果其他读者朋友有需要代码,请关注本号,加笔者微信联系。欢迎关注微信公众号“语和言”,本公众号将不定期发布对图书《Python程序设计(基于计算思维和新文科建设)》中的Python知识点进行解读和补充的内容。语和言公众号还有读者交流群,读者朋友可以入群一起讨论问题。
欢迎跟图书《Python程序设计(基于计算思维和新文科建设)》的作者胡凤国老师进行交流,电邮:cuchufengguo@163.com。
八、图书目录
图书《Python程序设计(基于计算思维和新文科建设)》目录如下(手机端可以用手指上下滑动下面灰色区域的文字来查看全部目录,电脑端可以用鼠标滚动滚轮或拖动下面文本框右边的滚动条来浏览全部目录):
8.2.4 关于元素可比较的有序序列类对象的通用操作10.3.3 用上下文管理语句with来管理文本文件读写12.12.1 datetime标准库定义的常用类参考文献