Skip to content

Instantly share code, notes, and snippets.

@physacco
Last active December 15, 2015 08:39
Show Gist options
  • Save physacco/5232093 to your computer and use it in GitHub Desktop.
Save physacco/5232093 to your computer and use it in GitHub Desktop.
This demo shows how to wrap io.Reader or io.Writer into a stream cipher.
package main
import (
"io"
"os"
)
type XReader struct {
io.Reader
Cipher []byte
Position uint64
}
func (rdr XReader) Read(p []byte) (n int, err error) {
n, err = rdr.Reader.Read(p)
keylen := uint64(len(rdr.Cipher))
if keylen > 0 {
for i := 0; i < n; i++ {
keypos := rdr.Position % keylen
p[i] ^= rdr.Cipher[keypos]
rdr.Position += 1
}
}
return
}
type XWriter struct {
io.Writer
Cipher []byte
Position uint64
}
func (wtr XWriter) Write(p []byte) (n int, err error) {
plen := len(p)
buf := make([]byte, plen)
keylen := uint64(len(wtr.Cipher))
if keylen > 0 {
for i := 0; i < plen; i++ {
keypos := wtr.Position % keylen
buf[i] = p[i] ^ wtr.Cipher[keypos]
wtr.Position += 1
}
}
n, err = wtr.Writer.Write(buf)
return
}
type XReadWriter struct {
XReader
XWriter
}
func main() {
key := []byte{1, 2, 3, 4, 5}
rdr := XReader{Reader: os.Stdin, Cipher: key}
wtr := XWriter{Writer: os.Stdout, Cipher: key}
xrw := XReadWriter{rdr, wtr}
buf := make([]byte, 100)
for {
n, err := xrw.Read(buf)
if err != nil {
if err == io.EOF {
break
}
panic(err)
}
xrw.Write(buf[:n])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment