2

我有这个代码来解压缩一个用密码加密的 zip 文件:

import zipfile

def main(pswd):
    file_name = 'somefile.zip'
    with zipfile.ZipFile(file_name) as file:
       return file.extractall(pwd = bytes(pswd, 'utf-8'))
print(main("password"))

它可以工作,但我希望如果我给函数一个正确的密码,它会提取它并返回例如“True”,或者使用错误的密码它返回“False”。如何改进我的代码?

4

2 回答 2

2

extractall密码错误时会引发功能RuntimeError,因此您可以执行以下操作

def main(pswd):
    file_name = "somefile.zip"
    with zipfile.ZipFile(file_name) as file:
        try:
            file.extractall(pwd=bytes(pswd, "utf-8"))
            return True
        except RuntimeError:
            return False
于 2021-12-22T16:07:30.980 回答
2

TL;DR:如果您想解压缩,请实施适当的异常处理。仅测试使用ZipFile.testzip()预设默认密码的密码。

改进建议

如果密码不正确,我会重新考虑返回布尔值的决定。

注意布尔错误返回

通常只有一个理由从方法返回布尔值:

  • 如果该方法应该测试某些东西,例如谓词函数 hasError()isValid(input). 最后阅读更多内容。

做或失败

你想要一个布尔值作为返回值,这样你就可以对失败做出反应。设计中可能存在逻辑缺陷。当我们调用该方法时,我们传递给它一个期望它成功,例如,通过给定的密码解锁 zip 文件并解压缩它。

但是,如果它失败了,我们希望对异常做出反应。这是通过异常处理完成的。

zipfile 的异常处理

在 Python 文档中:zipfile — 使用 ZIP 存档有很多原因会在extract()or期间引发异常extractall(),例如ValueErroror RuntimeError。这些异常的原因之一是密码错误,请参阅Decompression Pitfalls

由于密码错误/CRC校验和/ZIP格式或不支持的压缩方法/解密可能导致解压失败。

try-except您可以在错误处理期间通过使用Python中的块来捕获这些错误。

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 网站Code Review上对python - Zipfile 密码恢复程序的回答建议:

Zipfile.setpassword()与 ZipFile.testzip() 一起使用来检查密码。

首先用于.setpassword(pwd)设置用于此 zip 文件的默认密码。然后方法.testzip()测试它是否可以打开并读取 zip 文件 - 使用之前设置的默认密码

读取存档中的所有文件并检查它们的 CRC 和文件头。返回第一个坏文件的名称,否则返回 None。

同样,它引发异常或返回 non- 的原因None不仅仅是bad password

在这里,错误的密码也会引发 a 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 和密码:

从干净代码的角度来看的布尔值:

于 2021-12-22T21:05:55.620 回答