Windows下如何计算出某文件的MD5或SHA-1值?
BlackA
以前用 python 写过一个小工具,支持计算文件的 md5、sha1、sha224、sha256、sha3_224、sha3_256 等值。
用法:


代码如下:
# -*- coding: UTF-8 -*-
"""hash_checker - Get the hash value of a file.
Usage:
hash_checker.py [-h] [-v] [-l] [-m METHOD] [file_name]
Options:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-l, --list List all supported hash methods.
-m, --method METHOD The hash method. Defaults to 'md5'.
file_name The path of the file or directory.
Example:
$ hash_checker.py a.txt
$ hash_checker.py -m sha256 a.txt
CopyRight (c) 2024 yty All Rights Reserved.
"""
import hashlib
import argparse
import os
import os.path
import time
supported_method = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
'blake2b', 'blake2s',
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
)
def get_hash(file_path, method="md5"):
"""Get the hash value of a file.
Args:
file_path(str): The path of the file.
method(str, optional): The hash method. Defaults to 'md5'.
Returns:
str: The hash value of the file as a hexadecimal string.
"""
if method not in supported_method:
raise ValueError(f"Unsupported hash method: {method}")
# Open the file and get the hash
with open(file_path, 'rb') as f:
# Use the hashlib.file_digest() method to calculate the hash value of the file.
# This method bypass Python's I/O and use techniques such as zero-copy, improving
# the efficiency of file hashing.
hasher = hashlib.file_digest(f, method)
# A Slower implementation
# hasher = hashlib.new(method)
# while True:
# # Buffer size of 4096
# data = f.read(4096)
# if not data:
# break
# # Update the hash object
# hasher.update(data)
# return the hash as a hexadecimal string
return hasher.hexdigest()
def main():
start = time.time()
# Parse the command line arguments
parser = argparse.ArgumentParser(
prog="hash_checker.py",
description="Get the hash value of a file.",
epilog="CopyRight (c) 2024 yty All Rights Reserved."
)
parser.add_argument("-v", "--version", action="version", version="hash_checker (v1.0.0)")
parser.add_argument("-l", "--list", action="store_true", help="List all supported hash methods.")
parser.add_argument("-m", "--method", type=str, default="md5", metavar="METHOD",
choices=supported_method, help="The hash method. Defaults to 'md5'.")
parser.add_argument("file_name", type=str, nargs="?", help="The path of the file or directory.")
args = parser.parse_args()
# List all supported hash methods
if args.list:
print("Supported hash methods:")
for method in supported_method:
print(f" - {method}")
exit(0)
# Get the hash value of the file
if args.file_name is None:
parser.error("Please specify a file name.")
file_path = args.file_name
hash_value = get_hash(file_path, args.method)
end = time.time()
# Summary
abs_path = os.path.abspath(file_path)
stat = os.stat(file_path)
print(os.path.basename(abs_path))
print("-" * len(os.path.basename(abs_path)))
print()
print("Summary:")
print()
print(f"File path: {abs_path}")
print(f"File size: {stat.st_size} bytes")
try:
print(f"Create time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat.st_birthtime))}")
except AttributeError:
pass
print(f"Access time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat.st_atime))}")
print(f"Modified time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat.st_mtime))}")
print(f"{args.method} checksum: {hash_value}")
print()
print(f"Calculated {args.method} checksum in {end - start:.3f} seconds.")
print()
print("CopyRight (c) 2024 yty All Rights Reserved.")
if __name__ == '__main__':
main()