CXCV/Python/Models/HashModel.py

70 lines
2.0 KiB
Python

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