github.com/zhangyunhao116/wyhash@v0.4.1-0.20220217162229-7d42996fa899/internal/wyhashfv1/wyhash.go (about) 1 // Package wyhashfv1 implements wyhash final vesion 1. 2 // DO NOT USE IT, for test only. 3 package wyhashfv1 4 5 import ( 6 "math/bits" 7 "unsafe" 8 ) 9 10 const ( 11 s0 = 0xa0761d6478bd642f 12 s1 = 0xe7037ed1a0b428db 13 s2 = 0x8ebc6af09c88c6e3 14 s3 = 0x589965cc75374cc3 15 s4 = 0x1d8e4e27c47d124f 16 ) 17 18 //go:linkname readUnaligned32 runtime.readUnaligned32 19 func readUnaligned32(p unsafe.Pointer) uint32 20 21 //go:linkname readUnaligned64 runtime.readUnaligned64 22 func readUnaligned64(p unsafe.Pointer) uint64 23 24 func _wyr8(x []byte) uint64 { 25 array := *(*unsafe.Pointer)(unsafe.Pointer(&x)) 26 return readUnaligned64(array) 27 } 28 29 func _wyr4(x []byte) uint64 { 30 array := *(*unsafe.Pointer)(unsafe.Pointer(&x)) 31 return uint64(readUnaligned32(array)) 32 } 33 34 func _wyr3(x []byte, k int) uint64 { 35 return uint64(x[0])<<16 | uint64(x[k>>1])<<8 | uint64(x[k-1]) 36 } 37 38 func _wymix(a, b uint64) uint64 { 39 hi, lo := bits.Mul64(a, b) 40 return hi ^ lo 41 } 42 43 func _wyfinish16(p []byte, length int, seed uint64) uint64 { 44 var a, b uint64 45 i := len(p) 46 if i < 8 { 47 if i > 4 { 48 a = _wyr4(p) 49 b = _wyr4(p[i-4:]) 50 } else if i == 4 { 51 a = _wyr4(p) 52 b = 0 53 } else if i != 0 { 54 a = _wyr3(p, i) 55 b = 0 56 } else { // i == 0 57 a, b = 0, 0 58 } 59 } else if i == 8 { 60 a = _wyr8(p) 61 b = 0 62 } else { 63 a = _wyr8(p) 64 b = _wyr8(p[i-8:]) 65 } 66 return _wymix(s1^uint64(length), _wymix(a^s1, b^seed)) 67 } 68 69 func _wyfinish(p []byte, length int, seed uint64) uint64 { 70 i := len(p) 71 if i <= 16 { 72 return _wyfinish16(p, length, seed) 73 } 74 // _wyfinish(p+16,len,_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed),secret,i-16); 75 return _wyfinish(p[16:], length, _wymix(_wyr8(p)^s1, _wyr8(p[8:])^seed)) 76 } 77 78 func Sum64(p []byte) uint64 { 79 var seed uint64 = s0 80 length := len(p) 81 if len(p) > 64 { 82 var see1 = seed 83 for len(p) > 64 { 84 // seed=_wymix(_wyr8(p)^secret[1], _wyr8(p+8)^seed)^_wymix(_wyr8(p+16)^secret[2], _wyr8(p+24)^seed); 85 // see1=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see1)^_wymix(_wyr8(p+48)^secret[4],_wyr8(p+56)^see1); 86 // p+=64; i-=64; 87 seed = _wymix(_wyr8(p)^s1, _wyr8(p[8:])^seed) ^ _wymix(_wyr8(p[16:])^s2, _wyr8(p[24:])^seed) 88 see1 = _wymix(_wyr8(p[32:])^s3, _wyr8(p[40:])^see1) ^ _wymix(_wyr8(p[48:])^s4, _wyr8(p[56:])^see1) 89 p = p[64:] 90 } 91 seed ^= see1 92 } 93 return _wyfinish(p, length, seed) 94 } 95 96 func Sum64WithSeed(p []byte, seed uint64) uint64 { 97 length := len(p) 98 if len(p) > 64 { 99 var see1 = seed 100 for len(p) > 64 { 101 // seed=_wymix(_wyr8(p)^secret[1], _wyr8(p+8)^seed)^_wymix(_wyr8(p+16)^secret[2], _wyr8(p+24)^seed); 102 // see1=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see1)^_wymix(_wyr8(p+48)^secret[4],_wyr8(p+56)^see1); 103 // p+=64; i-=64; 104 seed = _wymix(_wyr8(p)^s1, _wyr8(p[8:])^seed) ^ _wymix(_wyr8(p[16:])^s2, _wyr8(p[24:])^seed) 105 see1 = _wymix(_wyr8(p[32:])^s3, _wyr8(p[40:])^see1) ^ _wymix(_wyr8(p[48:])^s4, _wyr8(p[56:])^see1) 106 p = p[64:] 107 } 108 seed ^= see1 109 } 110 return _wyfinish(p, length, seed) 111 }