Coverage for app/venv/lib/python3.14/site-packages/weblate/utils/hash.py: 79%

22 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 07:15 +0000

1# Copyright © Michal Čihař <michal@weblate.org> 

2# 

3# SPDX-License-Identifier: GPL-3.0-or-later 

4 

5from __future__ import annotations 

6 

7from typing import TYPE_CHECKING, Any 

8 

9from siphashc import siphash 

10 

11if TYPE_CHECKING: 11 ↛ 12line 11 didn't jump to line 12 because the condition on line 11 was never true

12 from collections.abc import Mapping 

13 

14 

15def raw_hash(*parts: str) -> int: 

16 """Calculate checksum identifying translation.""" 

17 if not parts: 17 ↛ 18line 17 didn't jump to line 18 because the condition on line 17 was never true

18 data = "" 

19 elif len(parts) == 1: 

20 data = parts[0] 

21 else: 

22 data = "".join(part for part in parts) 

23 return siphash("Weblate Sip Hash", data) 

24 

25 

26def calculate_dict_hash(data: Mapping[str, Any]) -> int: 

27 """ 

28 Calculate checksum of a dict. 

29 

30 * Ordering independent. 

31 * Coerces all values to string. 

32 

33 Returns unsigned int. 

34 """ 

35 return raw_hash(*(f"{part[0]}:{part[1]}" for part in sorted(data.items()))) 

36 

37 

38def calculate_hash(*parts: str) -> int: 

39 """Calculate checksum identifying translation.""" 

40 # Need to convert it from unsigned 64-bit int to signed 64-bit int 

41 return raw_hash(*parts) - 2**63 

42 

43 

44def calculate_checksum(*parts: str) -> str: 

45 """Calculate siphashc checksum for given strings.""" 

46 return format(raw_hash(*parts), "016x") 

47 

48 

49def checksum_to_hash(checksum: str) -> int: 

50 """Convert hex to id_hash (signed 64-bit int).""" 

51 return int(checksum, 16) - 2**63 

52 

53 

54def hash_to_checksum(id_hash: int) -> str: 

55 """Convert id_hash (signed 64-bit int) to unsigned hex.""" 

56 return format(id_hash + 2**63, "016x")