#!/usr/bin/env python3 # -*- coding: utf-8 -*- from hashlib import md5, sha1, sha256, blake2b from zlib import crc32 from typing import Self, Protocol from Interfaces.Application.CXCVInterface import CXCVInterface class HashAlgorithm(Protocol): def update(self:Self, data:bytes) -> None: ... def hexdigest(self:Self) -> str: ... class CRC32HashAlgorithm(HashAlgorithm): def __init__(self:Self) -> None: self.__value:int = 0 def update(self:Self, data:bytes) -> None: self.__value = crc32(data, self.__value) def hexdigest(self:Self) -> str: return f"{self.__value & 0xFFFFFFFF:08x}" class HashModel(): def __init__(self:Self, cxcv:CXCVInterface, data:bytes = b"", chunk_size:int = 4096) -> None: self.cxcv:CXCVInterface = cxcv self.__chunk_size:int = chunk_size self.md5:str = "" self.sha1:str = "" self.sha256:str = "" self.blake2b:str = "" self.crc32:str = "" self.__hashes:list[HashAlgorithm] = ["md5", "sha1", "sha256", "blake2b", "crc32"] self.__algorithms:list[HashAlgorithm] = [ method() for method in (md5, sha1, sha256, blake2b, CRC32HashAlgorithm) ] len(data) and self.update(data) def __update_chunk(self:Self, chunk:bytes) -> None: for hash_algorithm in self.__algorithms: hash_algorithm.update(chunk) def update(self:Self, data:bytes|str) -> None: done:bool = False if isinstance(data, bytes): while data: chunk:bytes = data[:self.__chunk_size] data = data[self.__chunk_size:] self.__update_chunk(chunk) done = True elif isinstance(data, str): self.cxcv.files.load_by_chunks(data, self.__update_chunk, self.__chunk_size) done = True if done: name:str for name in self.__hashes: setattr(self, name, getattr(self.__algorithms[self.__hashes.index(name)], "hexdigest")())