From 4cf229d9f0fd302d5c748421c2c2f3ceafbc0648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20CH=C3=8AN=C3=89?= <66779630+Sarbatore@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:29:34 +0200 Subject: [PATCH 1/4] Add joaat function for non-cryptographic hashing Implement the Jenkins-One-At-A-Time hash function. --- hashes/joaat.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 hashes/joaat.py diff --git a/hashes/joaat.py b/hashes/joaat.py new file mode 100644 index 000000000000..f31b477d5c40 --- /dev/null +++ b/hashes/joaat.py @@ -0,0 +1,22 @@ +""" +The Bob Jenkins hash is a fast, non-cryptographic hash function +designed for general-purpose use, such as hash table lookups. + +source: https://en.wikipedia.org/wiki/Jenkins_hash_function +""" + +def joaat(key: str) -> int: + hash = 0 + mask = 0xFFFFFFFF + key_bytes = key.encode('utf-8') + + for byte in key_bytes: + hash = (hash + byte) & mask + hash = (hash + (hash << 10)) & mask + hash = (hash ^ (hash >> 6)) & mask + + hash = (hash + (hash << 3)) & mask + hash = (hash ^ (hash >> 11)) & mask + hash = (hash + (hash << 15)) & mask + + return hash From 42139fda622aea5fa6ee555bb80046f8e2bec0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20CH=C3=8AN=C3=89?= <66779630+Sarbatore@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:05:25 +0200 Subject: [PATCH 2/4] Add doctest for joaat function Added doctest examples for the joaat function and included a main block to run tests. --- hashes/joaat.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/hashes/joaat.py b/hashes/joaat.py index f31b477d5c40..677803ad3fe1 100644 --- a/hashes/joaat.py +++ b/hashes/joaat.py @@ -6,9 +6,19 @@ """ def joaat(key: str) -> int: + """ + Calculate Jenkins One-at-a-Time hash for a key. + + >>> joaat("apple") + 2297466611 + >>> joaat("test") + 1064684737 + >>> joaat("") + 0 + """ hash = 0 mask = 0xFFFFFFFF - key_bytes = key.encode('utf-8') + key_bytes = key.encode("utf-8") for byte in key_bytes: hash = (hash + byte) & mask @@ -20,3 +30,7 @@ def joaat(key: str) -> int: hash = (hash + (hash << 15)) & mask return hash + +if __name__ == "__main__": + import doctest + doctest.testmod() From c9376b9ca322d9b0928da3a7574fcb053090cc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20CH=C3=8AN=C3=89?= <66779630+Sarbatore@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:14:36 +0200 Subject: [PATCH 3/4] Refactor joaat function variable names for prevent shadowing --- hashes/joaat.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/hashes/joaat.py b/hashes/joaat.py index 677803ad3fe1..be5539f99312 100644 --- a/hashes/joaat.py +++ b/hashes/joaat.py @@ -8,7 +8,7 @@ def joaat(key: str) -> int: """ Calculate Jenkins One-at-a-Time hash for a key. - + >>> joaat("apple") 2297466611 >>> joaat("test") @@ -16,20 +16,20 @@ def joaat(key: str) -> int: >>> joaat("") 0 """ - hash = 0 + hash_value = 0 mask = 0xFFFFFFFF key_bytes = key.encode("utf-8") - + for byte in key_bytes: - hash = (hash + byte) & mask - hash = (hash + (hash << 10)) & mask - hash = (hash ^ (hash >> 6)) & mask - - hash = (hash + (hash << 3)) & mask - hash = (hash ^ (hash >> 11)) & mask - hash = (hash + (hash << 15)) & mask - - return hash + hash_value = (hash_value + byte) & mask + hash_value = (hash_value + (hash_value << 10)) & mask + hash_value = (hash_value ^ (hash_value >> 6)) & mask + + hash_value = (hash_value + (hash_value << 3)) & mask + hash_value = (hash_value ^ (hash_value >> 11)) & mask + hash_value = (hash_value + (hash_value << 15)) & mask + + return hash_value if __name__ == "__main__": import doctest From 0ac7d1fc52adce36fd69ccc97415a51b1231893d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 15:15:06 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- hashes/joaat.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hashes/joaat.py b/hashes/joaat.py index be5539f99312..cdedc42b3933 100644 --- a/hashes/joaat.py +++ b/hashes/joaat.py @@ -5,6 +5,7 @@ source: https://en.wikipedia.org/wiki/Jenkins_hash_function """ + def joaat(key: str) -> int: """ Calculate Jenkins One-at-a-Time hash for a key. @@ -31,6 +32,8 @@ def joaat(key: str) -> int: return hash_value + if __name__ == "__main__": import doctest + doctest.testmod()