From 3bb8e4c396d8894c7c0f71f121f5844f940516bf Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Tue, 17 Jul 2012 17:20:13 +0100 Subject: [PATCH] opr: Add opr_jhash_opaque Add a function which can be used to obtain a hash of an arbitrary opaque string of arbitrary length Change-Id: I9e6aa29fa06a54976b81eda399c8838b73007962 Reviewed-on: http://gerrit.openafs.org/7978 Reviewed-by: Derrick Brashear Tested-by: BuildBot --- src/opr/jhash.h | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/opr/.gitignore | 1 + tests/opr/jhash-t.c | 13 +++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/opr/jhash.h b/src/opr/jhash.h index 27306c9..6e9bc79 100644 --- a/src/opr/jhash.h +++ b/src/opr/jhash.h @@ -103,4 +103,46 @@ opr_jhash_int(afs_uint32 a, afs_uint32 initval) { return c; } +static_inline afs_uint32 +opr_jhash_opaque(const void *val, size_t length, afs_uint32 initval) +{ + const unsigned char *str = (const unsigned char *) val; + afs_uint32 a,b,c; + afs_uint32 k[3]; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + (((afs_uint32)length)<<2) + initval; + + while (length > 12) { + memcpy(&k, str, 12); + a += k[0]; + b += k[1]; + c += k[2]; + opr_jhash_mix(a, b, c); + length -= 12; + str += 12; + } + + /* All the case statements fall through */ + switch(length) { + case 12 : c += (afs_uint32) str[11]<<24; + case 11 : c += (afs_uint32) str[10]<<16; + case 10 : c += (afs_uint32) str[9]<<8; + case 9 : c += (afs_uint32) str[8]; + case 8 : b += (afs_uint32) str[7]<<24; + case 7 : b += (afs_uint32) str[6]<<16; + case 6 : b += (afs_uint32) str[5]<<8; + case 5 : b += (afs_uint32) str[4]; + case 4 : a += (afs_uint32) str[3]<<24; + case 3 : a += (afs_uint32) str[2]<<16; + case 2 : a += (afs_uint32) str[1]<<8; + case 1 : a += (afs_uint32) str[0]; + opr_jhash_final(a, b, c); + case 0: /* case 0: nothing left to add */ + break; + } + + return c; +} + #endif diff --git a/tests/opr/.gitignore b/tests/opr/.gitignore index 578ee06..0f8cdbb 100644 --- a/tests/opr/.gitignore +++ b/tests/opr/.gitignore @@ -6,3 +6,4 @@ /rbtree-t /queues-t /time-t +/uuid-t diff --git a/tests/opr/jhash-t.c b/tests/opr/jhash-t.c index 80bdf70..a802fe5 100644 --- a/tests/opr/jhash-t.c +++ b/tests/opr/jhash-t.c @@ -39,7 +39,7 @@ int main(int argc, char **argv) { - plan(8); + plan(11); uint32_t test[] = {3526055646, 2064483663, 3234460805, 3963629775}; is_int(256, opr_jhash_size(8), "opr_jhash_size returns expected value"); @@ -57,5 +57,14 @@ main(int argc, char **argv) is_int(1100796964, opr_jhash_int(test[0], 0), "single value works through jhash_int"); - return 0; + is_int(0xdeadbeef, opr_jhash_opaque("", 0, 0), + "Hashing an empty string works"); + + is_int(2748273291, + opr_jhash_opaque("Four score and seven years ago", 30, 0), + "Hashing a string with a 0 initval works"); + is_int(1389900913, + opr_jhash_opaque("Four score and seven years ago", 30, 1), + "Hashing a string with a 1 initval works"); + return 0; } -- 1.9.4