Below is the hash function implementation of the roguewave library. It returns a 32 bit hash. The core operation is A = B ^ ((C << 5) | (C >> 27)). Is this hash safe to use as a password check or is it possible to retrieve all used B's by reversing it?
const unsigned RW_HASH_SHIFT = 5;
inline static void mash(unsigned& hash, unsigned chars)
{
hash = (chars ^
((hash << RW_HASH_SHIFT) |
(hash >> (RWBITSPERBYTE*sizeof(unsigned) - RW_HASH_SHIFT))));
}
unsigned
RWCStringRef::hash() const
{
unsigned hv = (unsigned)length(); // Mix in the string length.
unsigned i = length()*sizeof(char)/sizeof(unsigned);
const unsigned* p = (const unsigned*)data();
{
while (i--)
mash(hv, *p++); // XOR in the characters.
}
// XOR in any remaining characters:
if ((i = length()*sizeof(char)%sizeof(unsigned)) != 0) {
unsigned h = 0;
const char* c = (const char*)p;
while (i--)
h = ((h << RWBITSPERBYTE*sizeof(char)) | *c++);
mash(hv, h);
}
return hv;
}
sizeof(char)
is 1. Always. By design. By definition. Don't computesizeof(char)
.sizeof(char)
to 1 and optimise out theimul
anyway. I personally thinksizeof(char)
is a good thing to include, as it implies that the size of the type is relevant. That way, if you move towchar_t
or similar later to gain Unicode support, it's obvious that you need to change that calculation too.1
is a most descriptive term thansizeof(char)
.