I have range of hex numbers like these
0xabcd****
0xabdc**89
0x****abcd
0xde****ab
# 50 or so more entries like these
# where * is any hex number
I need a hash a function that will accept a 4byte value and generate Y/N answer for membership.
I tried using gperf but unfortunately it doesn't interpret * as wildcard. Has anyone faced this problem before? My code is in C.
If I can trust my arithmetic, each
****
has 16^4 possible values, so the four wild-card specs enumerate3 * 16^4 + 16^2
values - something on the order of 200,000 - a bit out of the remit of gperf (its docs say a "large" key set is 15,000).Wildcards mean regular expressions for me, so why not try that? Here's a try that defines "4byte value" as a uint32_t, and presents a text encoding of such a value to the
regex(3)
machinery. This may well not be what you were looking for, but as it was fun to cobble up, here you go.The responses to this reminded me of the question itself, and on reflection a more straightforward way occurred to me. Why the better answers don't just occur first, I'll never know.
Anyway, don't use regular expressions, just a value and a mask. The code above loses its
matcher_init
call (along with everything regex-related), and thematcher_matches
call support could look like the following. The looked-for values match the additional 46 I produced for the first answer, so the same test code in the first answer'smain
will continue to work.I suppose you could sort the struct vm array so that entries with fewer bits set in the mask occur first and buy a modest performance gain, but even as is this second attempt is about five times faster than the regex-based one for me.
Wildcards are now the zeros in the
mask
field of the struct, with corresponding bits "don't care" values (set to zero) in theval
field.