【问题标题】:ZipFile: Check for correct PasswordZipFile:检查密码是否正确
【发布时间】:2023-03-17 19:39:02
【问题描述】:

我有这个代码来解压缩一个用密码加密的 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”。如何改进我的代码?

【问题讨论】:

    标签: python python-zipfile


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案2】:

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

      改进建议

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

      注意布尔错误返回

      通常只有一个原因从方法返回布尔值:

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

      要么失败,要么失败

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

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

      zipfile 的异常处理

      在 Python 文档中:zipfile — Work with ZIP archivesextract()extractall() 期间引发异常的原因有很多,例如ValueErrorRuntimeError。这些异常的原因之一是密码错误,请参阅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 和密码:

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

      【讨论】:

        猜你喜欢
        • 2015-12-28
        • 1970-01-01
        • 2017-07-24
        • 1970-01-01
        • 1970-01-01
        • 2016-09-19
        • 2016-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多