1+ module Hash
2+ export H, H₈,H₁₆, H8, H16
3+
4+ const INIT8 = UInt8[0x12 , 0x34 , 0x56 , 0x78 , 0x9a , 0xbc , 0xde , 0xf0 ]
5+ const K8 = UInt8[0x1f , 0x2b , 0x3c , 0x4d , 0x5e , 0x6a , 0x7d , 0x8e ]
6+
7+ rotate (x:: UInt8 , n:: Int ) = ((x >> n) | (x << (8 - n))) % UInt8
8+ rotate (x:: UInt16 , n:: Int ) = ((x >> n) | (x << (16 - n))) % UInt16
9+
10+ function pad8 (msg:: Vector{UInt8} )
11+ len = length (msg)
12+ padded = copy (msg)
13+ push! (padded, 0x80 )
14+ while (length (padded) % 8 ) != 7
15+ push! (padded, 0x00 )
16+ end
17+ push! (padded, UInt8 (len % 256 ))
18+ return padded
19+ end
20+
21+ function compress_block8 (block:: Vector{UInt8} , state:: Vector{UInt8} )
22+ W = copy (block)
23+ for i in 1 : 8
24+ W[i] ⊻= K8[i]
25+ W[i] = rotate (W[i], i % 8 + 1 )
26+ end
27+ for i in 1 : 8
28+ state[i] = rotate (state[i] ⊻ W[i], i)
29+ end
30+ end
31+
32+ function tiny_hash8 (msg:: Vector{UInt8} )
33+ padded = pad8 (msg)
34+ state = copy (INIT8)
35+ for i in 1 : 8 : length (padded)
36+ block = padded[i: i+ 7 ]
37+ compress_block8 (block, state)
38+ end
39+ result = state[1 ]
40+ for i in 2 : 8
41+ result ⊻= rotate (state[i], i)
42+ end
43+ return result
44+ end
45+ tiny_hash8 (msg:: String ) = tiny_hash8 (Vector {UInt8} (codeunits (msg)))
46+
47+ function tiny_hash16 (msg:: Vector{UInt8} )
48+ acc = UInt16 (0xabcd )
49+ for (i, byte) in enumerate (msg)
50+ acc ⊻= UInt16 (byte) << (i % 8 )
51+ acc = (acc << 5 ) ⊻ (acc >> 3 )
52+ end
53+ return acc
54+ end
55+ tiny_hash16 (msg:: String ) = tiny_hash16 (Vector {UInt8} (codeunits (msg)))
56+
57+ function H8 (msg:: Union{String, Vector{UInt8}} )
58+ bytes = msg isa String ? Vector {UInt8} (codeunits (msg)) : msg
59+ return tiny_hash8 (bytes)
60+ end
61+
62+ function H16 (msg:: Union{String, Vector{UInt8}} )
63+ bytes = msg isa String ? Vector {UInt8} (codeunits (msg)) : msg
64+ return tiny_hash16 (bytes)
65+ end
66+
67+ H (msg:: Union{String, Vector{UInt8}} ) = H8 (msg)
68+ H₈ (msg:: Union{String, Vector{UInt8}} ) = H8 (msg)
69+ H₁₆ (msg:: Union{String, Vector{UInt8}} ) = H16 (msg)
70+ end
0 commit comments