You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.1 KiB
111 lines
3.1 KiB
#ifndef YDWEStringHashIncluded
|
|
#define YDWEStringHashIncluded
|
|
|
|
#if WARCRAFT_VERSION >= 124
|
|
library YDWEStringHash
|
|
endlibrary
|
|
#else
|
|
#include "Util/YDWEChar.j"
|
|
#include "Util/YDWEBitwise.j"
|
|
library YDWEStringHash requires YDWEChar, YDWEBitwise
|
|
private function SH_StringChar takes string s, integer n returns integer
|
|
local string ss = SubString(s, n, n+1)
|
|
|
|
if (ss == "/") then
|
|
set ss = "\\"
|
|
endif
|
|
|
|
return YDWEChar_ord(ss)
|
|
endfunction
|
|
|
|
private function SH_StringLong takes string s, integer n returns integer
|
|
return ((SH_StringChar(s, n+3)*256+SH_StringChar(s, n+2))*256+SH_StringChar(s, n+1))*256+SH_StringChar(s, n)
|
|
endfunction
|
|
|
|
#define T1(A, B, C) YDNL \
|
|
set A = YDWEBitwise_XOR(YDWEBitwise_RShift(C, 13), A - B - C) YDNL \
|
|
set B = YDWEBitwise_XOR(YDWEBitwise_LShift(A, 8), B - C - A) YDNL \
|
|
set C = YDWEBitwise_XOR(YDWEBitwise_RShift(B, 13), C - A - B) YDNL \
|
|
set A = YDWEBitwise_XOR(YDWEBitwise_RShift(C, 12), A - B - C) YDNL \
|
|
set B = YDWEBitwise_XOR(YDWEBitwise_LShift(A, 16), B - C - A) YDNL \
|
|
set C = YDWEBitwise_XOR(YDWEBitwise_RShift(B, 5), C - A - B) YDNL \
|
|
set A = YDWEBitwise_XOR(YDWEBitwise_RShift(C, 3), A - B - C) YDNL \
|
|
set B = YDWEBitwise_XOR(YDWEBitwise_LShift(A, 10), B - C - A) YDNL \
|
|
set C = YDWEBitwise_XOR(YDWEBitwise_RShift(B, 15), C - A - B)
|
|
|
|
private function StringHashEx takes string s, integer len returns integer
|
|
local integer n = 0
|
|
local integer sizt_t = len
|
|
local integer A = $9E3779B9
|
|
local integer B = $9E3779B9
|
|
local integer C = 0
|
|
|
|
loop
|
|
exitwhen len < 12
|
|
set A = A + SH_StringLong(s, n)
|
|
set B = B + SH_StringLong(s, n+4)
|
|
set C = C + SH_StringLong(s, n+8)
|
|
T1(A, B, C)
|
|
set n = n + 12
|
|
set len = len - 12
|
|
endloop
|
|
|
|
set C = C + sizt_t
|
|
|
|
if (len == 11) then
|
|
set C = C + SH_StringChar(s, n+10)*$01000000
|
|
set len = len - 1
|
|
endif
|
|
if (len == 10) then
|
|
set C = C + SH_StringChar(s, n+9)*$00010000
|
|
set len = len - 1
|
|
endif
|
|
if (len == 9) then
|
|
set C = C + SH_StringChar(s, n+8)*$00000100
|
|
set len = len - 1
|
|
endif
|
|
if (len == 8) then
|
|
set B = B + SH_StringChar(s, n+7)*$01000000
|
|
set len = len - 1
|
|
endif
|
|
if (len == 7) then
|
|
set B = B + SH_StringChar(s, n+6)*$00010000
|
|
set len = len - 1
|
|
endif
|
|
if (len == 6) then
|
|
set B = B + SH_StringChar(s, n+5)*$00000100
|
|
set len = len - 1
|
|
endif
|
|
if (len == 5) then
|
|
set B = B + SH_StringChar(s, n+4)
|
|
set len = len - 1
|
|
endif
|
|
if (len == 4) then
|
|
set A = A + SH_StringChar(s, n+3)*$01000000
|
|
set len = len - 1
|
|
endif
|
|
if (len == 3) then
|
|
set A = A + SH_StringChar(s, n+2)*$00010000
|
|
set len = len - 1
|
|
endif
|
|
if (len == 2) then
|
|
set A = A + SH_StringChar(s, n+1)*$00000100
|
|
set len = len - 1
|
|
endif
|
|
if (len == 1) then
|
|
set A = A + SH_StringChar(s, n)
|
|
set len = len - 1
|
|
endif
|
|
|
|
T1(A, B, C)
|
|
#undef T1
|
|
return C
|
|
endfunction
|
|
|
|
function StringHash takes string s returns integer
|
|
return StringHashEx(StringCase(s, true), StringLength(s))
|
|
endfunction
|
|
endlibrary
|
|
#endif
|
|
|
|
#endif
|
|
|