SStrHash

From wowdev
Revision as of 17:56, 19 April 2020 by Schlumpf (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This function closely resembles the hashing used in MPQ files, but uses a way smaller table and index into that table. It is usually used with uppercase-backslash strings and does by default convert to upper before hashing.

Source of the hash table and seed/shift constants are unknown. Other MPQ related hashing uses a generated table, but this one is hardcoded in Storm.

This function is used in various hash tables in the client, as well as Chat "Translation" and DB2 Table Hashes.

static char upper_backslash (char c) {
  return c == '/' ? '\\' : toupper (c);
}
static uint32_t const s_hashtable[16] = {
  0x486E26EE, 0xDCAA16B3, 0xE1918EEF, 0x202DAFDB,
  0x341C7DC7, 0x1C365303, 0x40EF2D37, 0x65FD5E49,
  0xD6057177, 0x904ECE93, 0x1C38024F, 0x98FD323B,
  0xE3061AE7, 0xA39B0FA1, 0x9797F25F, 0xE4444563,
};
uint32_t SStrHash (char const* string, bool no_caseconv, uint32_t seed)
{
  assert (string);
  if (!seed) {
    seed = 0x7FED7FED;
  }

  uint32_t shift = 0xEEEEEEEE;
  while (*string) {
    char c = *string++;
    if (!no_caseconv) {
      c = upper_backslash (c);
    }

    seed = (s_hashtable[c >> 4] - s_hashtable[c & 0xF]) ^ (shift + seed);
    shift = c + seed + 33 * shift + 3;
  }

  return seed ? seed : 1;
}