Zane Shelley | 352293d | 2023-04-06 17:38:15 -0500 | [diff] [blame] | 1 | def hash_string(num_bytes: int, string: str) -> int: |
| 2 | """ |
| 3 | Converts a string into an integer hash value. This is primarily used to |
| 4 | convert register and isolation node names from the Chip and RAS Data into |
| 5 | integer values to save space in the data. |
| 6 | """ |
| 7 | |
| 8 | # This hash is a simple "n*s[0] + (n-1)*s[1] + ... + s[n-1]" algorithm, |
| 9 | # where s[i] is a chunk from the input string the length of i_bytes. |
| 10 | |
| 11 | # Currently only supporting 1:8 byte hashes |
| 12 | assert 1 <= num_bytes and num_bytes <= 8 |
| 13 | |
| 14 | # Start hashing each chunk |
| 15 | sumA = 0 |
| 16 | sumB = 0 |
| 17 | |
| 18 | # Iterate one chunk at a time |
| 19 | for i in range(0, len(string), num_bytes): |
| 20 | # Combine each chunk into a single integer value. If we reach the end |
| 21 | # of the string, pad with null characters. |
| 22 | chunk = 0 |
| 23 | for j in range(0, num_bytes): |
| 24 | chunk <<= 8 |
| 25 | chunk |= ord(string[i + j]) if (i + j < len(string)) else ord("\0") |
| 26 | |
| 27 | # Apply the simple hash |
| 28 | sumA += chunk |
| 29 | sumB += sumA |
| 30 | |
| 31 | # Mask off everything except the target number of bytes. |
| 32 | mask = 0xFFFFFFFFFFFFFFFF |
| 33 | sumB &= mask >> ((8 - num_bytes) * 8) |
| 34 | |
| 35 | return sumB |
| 36 | |
| 37 | |
| 38 | def hash_string_format(num_bytes: int, string: str) -> str: |
| 39 | """ |
| 40 | Returns a formatted hex string of the given string's hash value. |
| 41 | """ |
| 42 | return "{0:0{1}x}".format(hash_string(num_bytes, string), num_bytes * 2) |