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

TL;DR:解凍する場合は、適切な例外処理を実装してください。パスワードのみをテストするにはZipFile.testzip()、事前設定されたデフォルトのパスワードを使用します。

改善アドバイス

パスワードが正しくない場合はブール値を返すという決定を再考します。

ブール値のエラー リターンに関する注意

通常、メソッドからブール値を返す理由は 1 つだけです。

  • メソッドがpredicate-functionやなどの何かをテストする必要がある場合。最後にもっともっと読んでください。 hasError()isValid(input)

やるか失敗するか

失敗に反応できるように、戻り値としてブール値が必要です。設計に論理的な欠陥がある可能性があります。メソッドを呼び出すときは、成功することを期待して渡します。たとえば、指定されたパスワードで zip ファイルのロックを解除して抽出します。

ただし、失敗した場合は、例外に対応する必要があります。これは、例外処理によって行われます。

zipfile の例外処理

Python のドキュメント: zipfile — ZIP アーカイブextract()を操作するまたはextractall()の実行中に例外を発生させる理由は多数ありValueErrorますRuntimeError。これらの例外の原因の 1 つは、不正なパスワードです。解凍の落とし穴を参照してください。

パスワード/CRCチェックサム/ZIP形式が間違っているか、サポートされていない圧縮方法/復号化が原因で、解凍に失敗する場合があります。

try-exceptPython でブロックを使用すると、エラー処理中にそれらをキャッチできます。

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 to python - Zipfile password recovery programの回答は、次のことを示唆しています。

Zipfile.setpassword()ZipFile.testzip() で使用して、パスワードを確認します。

最初に、この zip ファイルで使用するデフォルトのパスワード.setpassword(pwd)を設定します。次にメソッドは、以前に設定したデフォルトのパスワードを使用して、zip ファイルを開いて読み取ることができるかどうかをテストします。.testzip()

アーカイブ内のすべてのファイルを読み取り、CRC とファイル ヘッダーをチェックします。最初の不良ファイルの名前を返すか、None を返します。

繰り返しになりますが、例外を発生させたり、 non- を返したりする理由は、単にパスワード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 とパスワードの操作:

クリーンコードの観点からのブール値:

于 2021-12-22T21:05:55.620 に答える