Source code for openmnglab.util.hashing

import hashlib
import struct
from array import array
from mmap import mmap
from os import PathLike
from pathlib import Path
from typing import Self, Any

try:
    from quantities import Quantity
except ImportError as _:
    Quantity = None


[docs]class Hash:
[docs] def __init__(self): self._hash = hashlib.sha3_224()
def path(self, d: Path | PathLike | bytes | str) -> Self: d = str(d) if isinstance(d, (Path, PathLike)) else d if isinstance(d, str): return self.str(d) elif isinstance(d, bytes): return self.update(d) return self def str(self, s: str) -> Self: self.update(s.encode("UTF8")) return self def int(self, i: int) -> Self: self.update(struct.pack("<q", i)) return self def float(self, f: float) -> Self: self.update(struct.pack("<d", f)) return self def dict(self, d: dict, fail=True) -> Self: for k, v in d.items(): self.dynamic(k, fail=fail) self.dynamic(v, fail=fail) return self def dynamic(self, v: Any, fail=True) -> Self: if isinstance(v, int): return self.int(v) elif isinstance(v, float): return self.float(v) elif isinstance(v, str): return self.str(v) elif isinstance(v, bool): return self.bool(v) elif isinstance(v, (bytes, bytearray, memoryview, array, mmap)): return self.update(v) elif isinstance(v, Quantity): return self.quantity(v) elif hasattr(v, "__hash__"): return self.update(v.__hash__()) if fail: raise Exception(f"Could not hash type {type(v)}") else: self.int(id(v)) return self def update(self, b: bytes | bytearray | memoryview | array | mmap) -> Self: self._hash.update(b) return self def digest(self) -> bytes: return self._hash.digest() def quantity(self, q: Quantity) -> Self: self.float(q.magnitude.item()) self.str(str(q.units)) return self def bool(self, b: bool) -> Self: int_repr = int(b) self.update(struct.pack("<q", int_repr)) return self