[docs]@versionchanged("4.1.1",reason="Checksum for entire folder is possible")@versionadded("4.1.0")classChecksum(BaseClass):""" Checksum engine Parameters ---------- path : str | Path Path to file/directory to perform checksum hash_mode : ChecksumMode | Literal["md5", "sha1", "sha256", "sha512"], optional Hash mode, by default ``"sha256"`` save_result_to_file : bool, optional Save checksum result(s) to file, by default ``False`` """def__init__(self,path:str|Path,hash_mode:(ChecksumMode|Literal["md5","sha1","sha256","sha512"])=ChecksumMode.SHA256,save_result_to_file:bool=False,)->None:""" Checksum engine Parameters ---------- path : str | Path Path to file/directory to perform checksum hash_mode : ChecksumMode | Literal["md5", "sha1", "sha256", "sha512"], optional Hash mode, by default ``"sha256"`` save_result_to_file : bool, optional Save checksum result(s) to file, by default ``False`` """self.path=Path(path)self.hash_mode=hash_modeself.save_result_to_file=save_result_to_fileself.checksum_result_file_name="checksum_results.txt"def_get_hash_engine(self):hash_mode=self.hash_modeifhash_mode.lower()=="md5":hash_engine=hashlib.md5()elifhash_mode.lower()=="sha1":hash_engine=hashlib.sha1()elifhash_mode.lower()=="sha256":hash_engine=hashlib.sha256()elifhash_mode.lower()=="sha512":hash_engine=hashlib.sha512()else:hash_engine=hashlib.md5()returnhash_enginedef_checksum_operation(self,file:Path|str,)->str:"""This performs checksum"""hash_engine=self._get_hash_engine().copy()withopen(Path(file),"rb")asf:# Read and hash the file in 4K chunks. Reading the whole# file at once might consume a lot of memory if it is# large.whileTrue:data=f.read(4096)iflen(data)==0:breakelse:hash_engine.update(data)returnhash_engine.hexdigest()# type: ignore
[docs]defchecksum(self,recursive:bool=True)->str:""" Perform checksum Parameters ---------- recursive : bool, optional Do checksum for every file in the folder (including child folder), by default ``True`` Returns ------- str Checksum hash """ifself.path.absolute().is_dir():# Dirnew_path=self.path.joinpath(self.checksum_result_file_name)# List of filesifrecursive:file_list:list[Path]=[xforxinself.path.glob("**/*")ifx.is_file()]else:file_list=[xforxinself.path.glob("*")ifx.is_file()]# Checksumres=[]forxintqdm(file_list,desc="Calculating hash",unit_scale=True):name=x.relative_to(self.path)res.append(f"{self._checksum_operation(x)} | {name}")output="\n".join(res)else:# Filenew_path=self.path.with_name(self.checksum_result_file_name)output=self._checksum_operation(self.path)# Save resultifself.save_result_to_file:withopen(new_path,"w",encoding="utf-8")asf:f.write(output)returnoutput