Created
May 12, 2014 07:35
-
-
Save magical/6206ceae96a96a1a0ec0 to your computer and use it in GitHub Desktop.
xorfiles.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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