-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfast_xor.go
More file actions
45 lines (41 loc) · 1.27 KB
/
fast_xor.go
File metadata and controls
45 lines (41 loc) · 1.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package byte_utils
// This file contains functions for xor-ing slices of bytes together.
import (
"encoding/binary"
)
// Sets dst to the xor of bytes in slices a and b, one byte at a time. Panics
// if b and dst aren't at least as long as a. It is valid for dst to be the
// same as either a or b.
func SimpleXor(dst, a, b []byte) {
for i := 0; i < len(a); i++ {
dst[i] = a[i] ^ b[i]
}
}
// Used to xor byte slices a and b, writing the result into dst. Based on
// github.com/golang/go/issues/31586#issuecomment-487436401. Panics if b and
// dst aren't at least as long as a (the length of the operation is determined
// by len(a). It's valid for dst to be the same as either a or b. Benchmarks
// on my machine (tm) indicate that this is over 3x faster than SimpleXor alone
// for 1 MB slices, though this may change depending on architecture.
func FastXor(dst, a, b []byte) {
n := binary.LittleEndian
var x, y uint64
for len(a) >= 32 {
x = n.Uint64(a)
y = n.Uint64(b)
n.PutUint64(dst, x^y)
x = n.Uint64(a[8:])
y = n.Uint64(b[8:])
n.PutUint64(dst[8:], x^y)
x = n.Uint64(a[16:])
y = n.Uint64(b[16:])
n.PutUint64(dst[16:], x^y)
x = n.Uint64(a[24:])
y = n.Uint64(b[24:])
n.PutUint64(dst[24:], x^y)
a = a[32:]
b = b[32:]
dst = dst[32:]
}
SimpleXor(dst, a, b)
}