Coverage for muutils / misc / hashing.py: 60%

20 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-02-18 02:51 -0700

1from __future__ import annotations 

2 

3import base64 

4import hashlib 

5import json 

6from typing import Any 

7 

8 

9def stable_hash(s: str | bytes) -> int: 

10 """Returns a stable hash of the given string. not cryptographically secure, but stable between runs""" 

11 # init hash object and update with string 

12 s_bytes: bytes 

13 if isinstance(s, str): 

14 s_bytes = s.encode("utf-8") 

15 else: 

16 s_bytes = s 

17 hash_obj: hashlib._Hash = hashlib.md5(s_bytes) # pyright: ignore[reportPrivateUsage] 

18 # get digest and convert to int 

19 return int.from_bytes(hash_obj.digest(), "big") 

20 

21 

22def stable_json_dumps(d: Any) -> str: # pyright: ignore[reportAny] 

23 return json.dumps( 

24 d, 

25 sort_keys=True, 

26 indent=None, 

27 ) 

28 

29 

30def base64_hash(s: str | bytes) -> str: 

31 """Returns a base64 representation of the hash of the given string. not cryptographically secure""" 

32 s_bytes: bytes 

33 if isinstance(s, str): 

34 s_bytes = bytes(s, "UTF-8") 

35 else: 

36 s_bytes = s 

37 hash_bytes: bytes = hashlib.md5(s_bytes).digest() 

38 hash_b64: str = base64.b64encode(hash_bytes, altchars=b"-_").decode() 

39 return hash_b64