Skip to content

Instantly share code, notes, and snippets.

@magical
Created May 12, 2014 07:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magical/6206ceae96a96a1a0ec0 to your computer and use it in GitHub Desktop.
Save magical/6206ceae96a96a1a0ec0 to your computer and use it in GitHub Desktop.
xorfiles.go
package main
import (
"fmt"
"io"
"os"
)
func main() {
if len(os.Args) != 4 {
fmt.Println("Usage: xorfiles file1 file2 out")
}
in1, err := os.Open(os.Args[1])
if err != nil {
fmt.Println(err)
return
}
in2, err := os.Open(os.Args[2])
if err != nil {
fmt.Println(err)
return
}
out, err := os.Create(os.Args[3])
if err != nil {
fmt.Println(err)
return
}
xor(out, in1, in2)
}
var buf1 [1 << 20]byte
var buf2 [1 << 20]byte
func xor(w io.Writer, r1, r2 io.Reader) {
var n1, n2, nn int
var err1, err2 error
for {
n1, err1 = r1.Read(buf1[:])
if n1 == 0 {
break
}
n2, err2 = r2.Read(buf2[:n1])
for n2 < n1 && err2 == nil {
nn, err2 = r2.Read(buf2[n2:n1])
n2 += nn
}
n := n1
if n1 > n2 {
n = n2
}
for i := range buf1[:n] {
buf1[i] ^= buf2[i]
}
_, err := w.Write(buf1[:n])
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
if n1 > n {
_, err = w.Write(buf1[n:n1])
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
}
if err1 != nil || err2 != nil {
break
}
}
if err1 != nil && err1 != io.EOF {
fmt.Fprintln(os.Stderr, err1)
}
if err2 != nil && err2 != io.EOF {
fmt.Fprintln(os.Stderr, err2)
}
io.Copy(w, r1)
io.Copy(w, r2)
}
package main
import (
"bytes"
"testing"
"testing/iotest"
)
func TestXor(t *testing.T) {
b1 := []byte("hello hello hello")
b2 := []byte("hello there")
want := append([]byte{}, b1...)
for i := range b2 {
want[i] ^= b2[i]
}
var got bytes.Buffer
xor(&got, bytes.NewReader(b1), bytes.NewReader(b2))
if !bytes.Equal(got.Bytes(), want) {
t.Errorf("xor(b1, b2): expected %v, got %v", want, got.Bytes())
}
got.Reset()
xor(&got, bytes.NewReader(b2), bytes.NewReader(b1))
if !bytes.Equal(got.Bytes(), want) {
t.Errorf("xor(b2, b1): expected %v, got %v", want, got.Bytes())
}
got.Reset()
xor(&got, iotest.HalfReader(bytes.NewReader(b1)),
iotest.HalfReader(bytes.NewReader(b2)))
if !bytes.Equal(got.Bytes(), want) {
t.Errorf("xor(HalfReader(b1), HalfReader(b2)): expected %v, got %v", want, got.Bytes())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment