TL;DR:如果你想解压缩,请实施适当的异常处理。要仅测试密码,请使用 ZipFile.testzip() 和预设的默认密码。
改进建议
如果密码不正确,我会重新考虑返回布尔值的决定。
注意布尔错误返回
通常只有一个原因从方法返回布尔值:
- 如果方法应该测试某些东西,比如谓词函数
hasError() 或isValid(input)。最后阅读更多内容。
要么失败,要么失败
你想要一个布尔值作为返回值,这样你就可以对失败做出反应。
设计中可能存在逻辑缺陷。当我们调用该方法时,我们传递给它一个期望它成功,例如通过给定的密码解锁 zip 文件并解压。
但是,如果它失败了,我们希望对异常做出反应。这是通过异常处理完成的。
zipfile 的异常处理
在 Python 文档中:zipfile — Work with ZIP archives 在extract() 或extractall() 期间引发异常的原因有很多,例如ValueError 或 RuntimeError。这些异常的原因之一是密码错误,请参阅Decompression Pitfalls:
由于密码错误/CRC校验和/ZIP格式或不支持的压缩方法/解密可能导致解压失败。
您可以在 Python 中使用 try-except 块在错误处理期间捕获这些错误。
import zipfile
def is_correct(pswd): # renamed from `main`
file_name = 'somefile.zip'
with zipfile.ZipFile(file_name) as file:
try:
file.extractall(pwd = bytes(pswd, 'utf-8'))
return True # correct password, decrypted and extracted successfully
except RuntimeError as e:
if e.args[0].startswith('Bad password for file'):
return False # incorrect password
raise e # TODO: properly handle exceptions?
print(is_correct("password"))
测试密码 - 无需提取
Stack Exchange 网站代码审查对python - Zipfile password recovery program 的回答建议:
使用Zipfile.setpassword() 和 ZipFile.testzip() 来检查密码。
首先使用.setpassword(pwd) 设置一个默认密码以用于此压缩文件。
然后方法 .testzip() 测试它是否可以打开并读取 zip 文件 - 使用之前设置的 默认密码:
读取存档中的所有文件并检查其 CRC 和文件头。返回第一个坏文件的名称,否则返回 None。
同样,它引发异常或返回非None 的原因可能不仅仅是密码错误。
同样,密码错误会引发RuntimeError,因此我们需要再次进行异常处理:
import zipfile
def is_correct(pswd):
file_name = 'somefile.zip'
pwd = bytes(pswd, 'utf-8')
zip = zipfile.ZipFile(file_name)
zip.setpassword(pwd)
try:
bad_file = zip.testzip() # if anything returned without error then password was correct
return True # ignore if bad file was found (integrity violated)
except RuntimeError as e:
if e.args[0].startswith('Bad password for file'):
return False
raise e # throw any other exception to print on console
passwords = ["password", "pass"]
for p in passwords:
print(f"'{p}' is correct?",is_correct(p))
打印:
“密码”正确吗?假的
“通过”正确吗?是的
另见
使用 ZipFile 和密码:
从干净代码的角度来看的布尔值: