| 1 | #include <array> |
|---|---|
| 2 | |
| 3 | #include <codec/seadHashCRC16.h> |
| 4 | |
| 5 | namespace sead |
| 6 | { |
| 7 | u16 HashCRC16::sTable[256]; |
| 8 | bool HashCRC16::sInitialized = false; |
| 9 | |
| 10 | void HashCRC16::initialize() |
| 11 | { |
| 12 | for (u32 i = 0; i < std::size(array: sTable); ++i) |
| 13 | { |
| 14 | u32 val = i; |
| 15 | for (int j = 0; j < 8; ++j) |
| 16 | val = ((val & 1) == 0) ? (val >> 1) : ((val >> 1) ^ 0xA001); |
| 17 | sTable[i] = val; |
| 18 | } |
| 19 | sInitialized = true; |
| 20 | } |
| 21 | |
| 22 | u32 HashCRC16::calcHash(const void* ptr, u32 size) |
| 23 | { |
| 24 | Context ctx; |
| 25 | return calcHashWithContext(context: &ctx, ptr, size); |
| 26 | } |
| 27 | |
| 28 | u32 HashCRC16::calcHashWithContext(Context* context, const void* ptr, u32 size) |
| 29 | { |
| 30 | if (!sInitialized) |
| 31 | initialize(); |
| 32 | |
| 33 | u32 hash = context->hash; |
| 34 | const u8* data = static_cast<const u8*>(ptr); |
| 35 | while (size--) |
| 36 | hash = sTable[*data++ ^ (hash & 0xFF)] ^ (hash >> 8); |
| 37 | context->hash = hash; |
| 38 | return hash; |
| 39 | } |
| 40 | |
| 41 | u32 HashCRC16::calcStringHash(const char* str) |
| 42 | { |
| 43 | Context ctx; |
| 44 | return calcStringHashWithContext(context: &ctx, str); |
| 45 | } |
| 46 | |
| 47 | u32 HashCRC16::calcStringHashWithContext(Context* context, const char* str) |
| 48 | { |
| 49 | if (!sInitialized) |
| 50 | initialize(); |
| 51 | |
| 52 | u32 hash = context->hash; |
| 53 | while (*str) |
| 54 | hash = sTable[*str++ ^ (hash & 0xFF)] ^ (hash >> 8); |
| 55 | context->hash = hash; |
| 56 | return hash; |
| 57 | } |
| 58 | |
| 59 | } // namespace sead |
| 60 |