TL;DR:解凍する場合は、適切な例外処理を実装してください。パスワードのみをテストするにはZipFile.testzip()
、事前設定されたデフォルトのパスワードを使用します。
改善アドバイス
パスワードが正しくない場合はブール値を返すという決定を再考します。
ブール値のエラー リターンに関する注意
通常、メソッドからブール値を返す理由は 1 つだけです。
- メソッドがpredicate-functionやなどの何かをテストする必要がある場合。最後にもっともっと読んでください。
hasError()
isValid(input)
やるか失敗するか
失敗に反応できるように、戻り値としてブール値が必要です。設計に論理的な欠陥がある可能性があります。メソッドを呼び出すときは、成功することを期待して渡します。たとえば、指定されたパスワードで zip ファイルのロックを解除して抽出します。
ただし、失敗した場合は、例外に対応する必要があります。これは、例外処理によって行われます。
zipfile の例外処理
Python のドキュメント: zipfile — ZIP アーカイブextract()
を操作するまたはextractall()
の実行中に例外を発生させる理由は多数ありValueError
ますRuntimeError
。これらの例外の原因の 1 つは、不正なパスワードです。解凍の落とし穴を参照してください。
パスワード/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 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 とパスワードの操作:
クリーンコードの観点からのブール値: