#!/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()