70 lines
2.0 KiB
Python
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")()) |