43 lines
1.1 KiB
C++
43 lines
1.1 KiB
C++
// Copyright 2024 The DMBMX2Tools Authors
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include <base/Types.hpp>
|
|
|
|
namespace dmtools::dmbmx {
|
|
|
|
/// Z-Axis' variant of the PJW hash algorithm.
|
|
///
|
|
/// # Safety
|
|
/// This function should *not* be given any input other than ASCII.
|
|
constexpr u32 zStringGenerateHash(const char* szString) {
|
|
const char* cursor = szString;
|
|
u32 hashTally {};
|
|
|
|
while(*cursor) {
|
|
u32 signExtendedVal = *cursor;
|
|
|
|
// If the character is in the ASCII range for lowercase alphabetical letters
|
|
// make it uppercase, by XORing with 0x20 (-= 0x20 works too). If not, don't modify the value.
|
|
if((signExtendedVal - 'a') < 26)
|
|
signExtendedVal ^= 0x20;
|
|
|
|
// Do PJW hash
|
|
signExtendedVal += (hashTally << 4);
|
|
hashTally = signExtendedVal & 0xf0000000;
|
|
|
|
if(hashTally != 0)
|
|
signExtendedVal ^= (hashTally >> 24);
|
|
|
|
hashTally = signExtendedVal & ~hashTally;
|
|
|
|
// Advance to the next byte
|
|
cursor++;
|
|
}
|
|
|
|
return hashTally;
|
|
}
|
|
|
|
static_assert(zStringGenerateHash("Park.zsc") == 0x066e3a33, "zStringGenerateHash is broken");
|
|
|
|
} // namespace dmtools::dmbmx
|