blob: ae7a0d8960d01fecc5a31ec4b7925c22c839218c [file] [log] [blame]
Caleb Palmera1c5fa52025-04-21 08:41:32 -05001#!/usr/bin/env python3
2
3import argparse
4
5
Zane Shelley352293d2023-04-06 17:38:15 -05006def hash_string(num_bytes: int, string: str) -> int:
7 """
8 Converts a string into an integer hash value. This is primarily used to
9 convert register and isolation node names from the Chip and RAS Data into
10 integer values to save space in the data.
11 """
12
13 # This hash is a simple "n*s[0] + (n-1)*s[1] + ... + s[n-1]" algorithm,
14 # where s[i] is a chunk from the input string the length of i_bytes.
15
16 # Currently only supporting 1:8 byte hashes
17 assert 1 <= num_bytes and num_bytes <= 8
18
19 # Start hashing each chunk
20 sumA = 0
21 sumB = 0
22
23 # Iterate one chunk at a time
24 for i in range(0, len(string), num_bytes):
25 # Combine each chunk into a single integer value. If we reach the end
26 # of the string, pad with null characters.
27 chunk = 0
28 for j in range(0, num_bytes):
29 chunk <<= 8
30 chunk |= ord(string[i + j]) if (i + j < len(string)) else ord("\0")
31
32 # Apply the simple hash
33 sumA += chunk
34 sumB += sumA
35
36 # Mask off everything except the target number of bytes.
37 mask = 0xFFFFFFFFFFFFFFFF
38 sumB &= mask >> ((8 - num_bytes) * 8)
39
40 return sumB
41
42
43def hash_string_format(num_bytes: int, string: str) -> str:
44 """
45 Returns a formatted hex string of the given string's hash value.
46 """
47 return "{0:0{1}x}".format(hash_string(num_bytes, string), num_bytes * 2)
Caleb Palmera1c5fa52025-04-21 08:41:32 -050048
49
50if __name__ == "__main__":
51
52 cli = argparse.ArgumentParser()
53 cli.add_argument("num_bytes", help="Number of bytes to hash to")
54 cli.add_argument("string_name", help="String to hash")
55 args = cli.parse_args()
56 print(hex(hash_string(int(args.num_bytes), args.string_name)))