85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
File Hash Calculator - Computes cryptographic hashes for files.
|
|
Supports: sha256, sha1, sha512, md5, blake2b, blake2s, crc32
|
|
"""
|
|
import argparse
|
|
import hashlib
|
|
import binascii
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def compute_hash(filepath: str, algorithm: str = "sha256", buffer_size: int = 65536) -> str:
|
|
"""Compute hash of a file using specified algorithm."""
|
|
algorithms = {
|
|
"sha256": hashlib.sha256,
|
|
"sha1": hashlib.sha1,
|
|
"sha512": hashlib.sha512,
|
|
"md5": hashlib.md5,
|
|
"blake2b": hashlib.blake2b,
|
|
"blake2s": hashlib.blake2s,
|
|
}
|
|
|
|
if algorithm not in algorithms:
|
|
raise ValueError(f"Unknown algorithm: {algorithm}. Available: {list(algorithms.keys())}")
|
|
|
|
hasher = algorithms[algorithm]()
|
|
|
|
with open(filepath, "rb") as f:
|
|
while True:
|
|
data = f.read(buffer_size)
|
|
if not data:
|
|
break
|
|
hasher.update(data)
|
|
|
|
return hasher.hexdigest()
|
|
|
|
|
|
def compute_crc32(filepath: str, buffer_size: int = 65536) -> str:
|
|
"""Compute CRC32 checksum."""
|
|
crc = 0
|
|
with open(filepath, "rb") as f:
|
|
while True:
|
|
data = f.read(buffer_size)
|
|
if not data:
|
|
break
|
|
crc = binascii.crc32(data, crc)
|
|
return format(crc & 0xFFFFFFFF, '08x')
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Compute file hashes")
|
|
parser.add_argument("file", help="File to hash")
|
|
parser.add_argument("-a", "--algorithm", default="sha256",
|
|
choices=["sha256", "sha1", "sha512", "md5", "blake2b", "blake2s", "crc32"],
|
|
help="Hash algorithm (default: sha256)")
|
|
parser.add_argument("-j", "--json", action="store_true",
|
|
help="Output as JSON")
|
|
|
|
args = parser.parse_args()
|
|
|
|
filepath = Path(args.file)
|
|
if not filepath.exists():
|
|
print(f"Error: File not found: {filepath}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
if args.algorithm == "crc32":
|
|
result = compute_crc32(str(filepath))
|
|
else:
|
|
result = compute_hash(str(filepath), args.algorithm)
|
|
|
|
if args.json:
|
|
import json
|
|
print(json.dumps({
|
|
"file": str(filepath),
|
|
"algorithm": args.algorithm,
|
|
"hash": result,
|
|
"length": len(result)
|
|
}))
|
|
else:
|
|
print(f"{args.algorithm}:{result}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |