github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/common/bitutil/bitutil.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:33</date> 10 //</624450072704192512> 11 12 //版权所有2013 Go作者。版权所有。 13 //此源代码的使用受BSD样式的控制 14 //可以在许可文件中找到的许可证。 15 16 //改编自:https://golang.org/src/crypto/cipher/xor.go 17 18 //包bitutil实现快速按位操作。 19 package bitutil 20 21 import ( 22 "runtime" 23 "unsafe" 24 ) 25 26 const wordSize = int(unsafe.Sizeof(uintptr(0))) 27 const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x" 28 29 //xorbytes xor是a和b中的字节。假定目标具有足够的 30 //空间。返回字节数xor'd。 31 func XORBytes(dst, a, b []byte) int { 32 if supportsUnaligned { 33 return fastXORBytes(dst, a, b) 34 } 35 return safeXORBytes(dst, a, b) 36 } 37 38 //FastXorBytes大容量XORS。它只适用于支持 39 //未对齐的读/写。 40 func fastXORBytes(dst, a, b []byte) int { 41 n := len(a) 42 if len(b) < n { 43 n = len(b) 44 } 45 w := n / wordSize 46 if w > 0 { 47 dw := *(*[]uintptr)(unsafe.Pointer(&dst)) 48 aw := *(*[]uintptr)(unsafe.Pointer(&a)) 49 bw := *(*[]uintptr)(unsafe.Pointer(&b)) 50 for i := 0; i < w; i++ { 51 dw[i] = aw[i] ^ bw[i] 52 } 53 } 54 for i := n - n%wordSize; i < n; i++ { 55 dst[i] = a[i] ^ b[i] 56 } 57 return n 58 } 59 60 //安全字节一个接一个。它适用于所有体系结构,独立于 61 //它是否支持未对齐的读/写。 62 func safeXORBytes(dst, a, b []byte) int { 63 n := len(a) 64 if len(b) < n { 65 n = len(b) 66 } 67 for i := 0; i < n; i++ { 68 dst[i] = a[i] ^ b[i] 69 } 70 return n 71 } 72 73 //AndBytes和A和B中的字节。假定目标具有足够的 74 //空间。返回字节数和'd'。 75 func ANDBytes(dst, a, b []byte) int { 76 if supportsUnaligned { 77 return fastANDBytes(dst, a, b) 78 } 79 return safeANDBytes(dst, a, b) 80 } 81 82 //FastAndBytes和批量。它只适用于支持 83 //未对齐的读/写。 84 func fastANDBytes(dst, a, b []byte) int { 85 n := len(a) 86 if len(b) < n { 87 n = len(b) 88 } 89 w := n / wordSize 90 if w > 0 { 91 dw := *(*[]uintptr)(unsafe.Pointer(&dst)) 92 aw := *(*[]uintptr)(unsafe.Pointer(&a)) 93 bw := *(*[]uintptr)(unsafe.Pointer(&b)) 94 for i := 0; i < w; i++ { 95 dw[i] = aw[i] & bw[i] 96 } 97 } 98 for i := n - n%wordSize; i < n; i++ { 99 dst[i] = a[i] & b[i] 100 } 101 return n 102 } 103 104 //安全字节和一个接一个。它适用于所有体系结构,独立于 105 //它是否支持未对齐的读/写。 106 func safeANDBytes(dst, a, b []byte) int { 107 n := len(a) 108 if len(b) < n { 109 n = len(b) 110 } 111 for i := 0; i < n; i++ { 112 dst[i] = a[i] & b[i] 113 } 114 return n 115 } 116 117 //ORBYTES或A和B中的字节。假定目标具有足够的 118 //空间。返回字节数或'd'。 119 func ORBytes(dst, a, b []byte) int { 120 if supportsUnaligned { 121 return fastORBytes(dst, a, b) 122 } 123 return safeORBytes(dst, a, b) 124 } 125 126 //FastOrbytes或大量。它只适用于支持 127 //未对齐的读/写。 128 func fastORBytes(dst, a, b []byte) int { 129 n := len(a) 130 if len(b) < n { 131 n = len(b) 132 } 133 w := n / wordSize 134 if w > 0 { 135 dw := *(*[]uintptr)(unsafe.Pointer(&dst)) 136 aw := *(*[]uintptr)(unsafe.Pointer(&a)) 137 bw := *(*[]uintptr)(unsafe.Pointer(&b)) 138 for i := 0; i < w; i++ { 139 dw[i] = aw[i] | bw[i] 140 } 141 } 142 for i := n - n%wordSize; i < n; i++ { 143 dst[i] = a[i] | b[i] 144 } 145 return n 146 } 147 148 //安全字节或一个接一个。它适用于所有体系结构,独立于 149 //它是否支持未对齐的读/写。 150 func safeORBytes(dst, a, b []byte) int { 151 n := len(a) 152 if len(b) < n { 153 n = len(b) 154 } 155 for i := 0; i < n; i++ { 156 dst[i] = a[i] | b[i] 157 } 158 return n 159 } 160 161 //测试字节测试输入字节片中是否设置了任何位。 162 func TestBytes(p []byte) bool { 163 if supportsUnaligned { 164 return fastTestBytes(p) 165 } 166 return safeTestBytes(p) 167 } 168 169 //FastTestBytes批量测试设置位。它只适用于那些 170 //支持未对齐的读/写。 171 func fastTestBytes(p []byte) bool { 172 n := len(p) 173 w := n / wordSize 174 if w > 0 { 175 pw := *(*[]uintptr)(unsafe.Pointer(&p)) 176 for i := 0; i < w; i++ { 177 if pw[i] != 0 { 178 return true 179 } 180 } 181 } 182 for i := n - n%wordSize; i < n; i++ { 183 if p[i] != 0 { 184 return true 185 } 186 } 187 return false 188 } 189 190 //safetestBytes一次测试一个字节的设置位。它适用于所有 191 //体系结构,独立于是否支持未对齐的读/写。 192 func safeTestBytes(p []byte) bool { 193 for i := 0; i < len(p); i++ { 194 if p[i] != 0 { 195 return true 196 } 197 } 198 return false 199 } 200