To do a portable hash, follow these rules:
Only use other portable-hash results or portably converted primitives as elements in your calculations.
Store the hash result as a value; never interpret it as a sequence of bytes.
All of the primitives that you use must be converted to a portable form, with precisely the same results on all machines. This means that you convert all primitive values to HashResult (unsigned
long
), using only 32 bits.
kMask32
is a named constant that stands for the masking value 0xFFFFFFFFU):
result = (HashResult) (x & kMask32);
unsigned
long
, the other is converted to unsigned
long
.unsigned
long
yields identical values on different machines as long as the number of bits in an unsigned
long
is the same.unsigned
long
is greater than or equal to 32, the least 32 bits of the result in from the previous step (c.) is the same across all such machines.double
and float
, the Hash supplied by Numerics.h
is portable.
result = Hash(x);
result = (x + y) & kMask32
If you want your hash function to return hash values that are uniformly distributed across what the return type can represent, send your result as a seed to a random number generator that returns values of that type. Because the semantics of the random number generator are to return numbers that are uniformly distributed, this makes your hash function also generate values with the same property.
In the future, the Taligent Application Environment will define APIs to assist in computing portable hashes. In the meantime, you might want to write your own helpers, such as a masking function.
For many objects, Hash (and comparison) aren't intrinsic properties of the objects, but of the collections they are inserted into. Thus, they shouldn't be implemented via member functions. To illustrate why this is a problem, consider TFontIdentifierStyle, which identifies the font to use for text in style sets and line layout. A hash function was added for line layout so that TFontIdentifierStyles could be found. This Hash function was based on the name of the font. However, no one realized that TStyle already defined a Hash function based on the type of the style--it was a TFontIdentifierStyle. So, when this new Hash function was introduced, TFontIdentifierStyles stopped working in style sets.
Strive for uniform distribution
Do not implement
Hash via member functions
[Contents]
[Previous]
[Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Generated with WebMaker