Skip to content

Instantly share code, notes, and snippets.

@flc
Created September 4, 2013 15:59
Show Gist options
  • Select an option

  • Save flc/6439105 to your computer and use it in GitHub Desktop.

Select an option

Save flc/6439105 to your computer and use it in GitHub Desktop.
A Tour of Go - Exercise: Rot13 Reader http://tour.golang.org/#61
package main
import (
"io"
"os"
"strings"
//"fmt"
"bytes"
)
var ascii_uppercase = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
var ascii_lowercase = []byte("abcdefghijklmnopqrstuvwxyz")
var ascii_uppercase_len = len(ascii_uppercase)
var ascii_lowercase_len = len(ascii_lowercase)
type rot13Reader struct {
r io.Reader
}
func rot13(b byte) byte {
pos := bytes.IndexByte(ascii_uppercase, b)
if pos != -1 {
return ascii_uppercase[(pos+13) % ascii_uppercase_len]
}
pos = bytes.IndexByte(ascii_lowercase, b)
if pos != -1 {
return ascii_lowercase[(pos+13) % ascii_lowercase_len]
}
return b
}
func (r rot13Reader) Read(p []byte) (n int, err error) {
n, err = r.r.Read(p)
for i := 0; i < n; i++ {
p[i] = rot13(p[i])
}
return n, err
}
func main() {
s := strings.NewReader(
"Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
@qianlongzt

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func rot13(b byte) byte {
	if b <= byte('z') && b >= byte('n') || b <= byte('Z') && b >= byte('N')  {
		return b - 13
	} else if b <= byte('m') && b >= byte('a') || b <= byte('M') && b >= byte('A') {
		return b + 13
	}
	return b
}
func (r rot13Reader) Read(b []byte) (int, error) {
	buf := make([]byte, len(b), cap(b))
	bits, err := r.r.Read(buf)
	for i := 0; i < bits; i ++ {
		b[i] = rot13(buf[i])
	}
	return bits, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@seefaq

seefaq commented Apr 22, 2017 •

Copy link
Copy Markdown
package main
import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct { r io.Reader }
func (t rot13Reader) Read(b []byte) (int,error) {
	n,e:=t.r.Read(b)
	for i:=0;i<n;i++ {
		switch {
		case b[i]>=110: b[i]-=13
		case b[i]>=97: b[i]+=13
		case b[i]>=78: b[i]-=13
		case b[i]>=65: b[i]+=13
		}
	}
	return n,e
}

func main() {
	s:=strings.NewReader("Lbh penqxrq gur pbqr!")
	r:=rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@so0k

so0k commented Jul 14, 2017 •

Copy link
Copy Markdown

just using the keys from the wiki article

package main

import (
	"io"
	"os"
	"strings"
)

//from the wikipedia article linked:
var enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var dec = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"

type rot13Reader struct {
	r io.Reader
}

func (rot rot13Reader) Read(b []byte) (n int, err error) {
	n, err = rot.r.Read(b)
	for i := 0; i < n; i++ { // := range b {	
		if j := strings.IndexByte(enc,b[i]); j >= 0 {
			b[i] = dec[j]
		}
	}
	return
}

func main() {
	s := strings.NewReader("Lbh ner na vqvbg!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@hjhee

hjhee commented Jul 27, 2017 •

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

var rot13_upper = []byte("NOPQRSTUVWXYZABCDEFGHIJKLM")
var rot13_lower = []byte("nopqrstuvwxyzabcdefghijklm")

func (rot *rot13Reader) Read(b []byte) (int, error) {
	n, err := rot.r.Read(b)
	if err != nil {
		return 0, err
	}
	for i := range b {
		if 'a' <= b[i] && b[i] <= 'z' {
			b[i] = rot13_lower[b[i]-'a']
		} else if 'A' <= b[i] && b[i] <= 'Z' {
			b[i] = rot13_upper[b[i]-'A']
		}
	}
	return n, nil
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@ellingit

ellingit commented Sep 8, 2017

Copy link
Copy Markdown

package main

import (
"io"
"os"
"strings"
)

type rot13Reader struct {
r io.Reader
}

func (rot *rot13Reader) Read(b []byte) (int, error) {
var capstart byte = 'A' + 13
var lowstart byte = 'a' + 13
n, err := rot.r.Read(b)

if err != nil {
	return 0, err
}

for i := range b {
	switch {
	case b[i] < 'A' || b[i] > 'z':
	case b[i] < capstart || (lowstart - 13 < b[i] && b[i] < lowstart):
		b[i] += 13
	default:
		b[i] -= 13
	}
}
return n, err

}

func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}

@hookenz

hookenz commented Nov 2, 2017

Copy link
Copy Markdown

My version. Not many solutions are checking for inner Read for error

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (r rot13Reader) Read(b []byte) (int, error) {
  size, err := r.r.Read(b)
  if err != nil {
	return 0, err  
  }
  
  for i, v := range b {
	if v >= 'a' && v <= 'm' || v >= 'A' && v <= 'M' {
		b[i] = v + 13
	} else if v >= 'n' && v <= 'z' || v >= 'N' && v <= 'Z' {
		b[i] = v - 13
	}
  }
  
  return size, nil
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@mateusfccp

mateusfccp commented Nov 3, 2017 •

Copy link
Copy Markdown

This is my final version. What about it?

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func rot13(b byte) byte {
	key := 'A' | (b & 0x20)
	if b & 0x40 == 0x40 {
		return key + ((b - key) + 13) % 26
	}
	return b
}

func (r rot13Reader) Read(b []byte) (int, error) {
	n, err := r.r.Read(b)
	if err != nil {
		return 0, err
	}
	for i := range b {
		b[i] = rot13(b[i])
	}
	return n, nil
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@anamorphism

anamorphism commented Feb 6, 2018 •

Copy link
Copy Markdown

This is my final version. What about it?

Off-by-one errors and incorrectly rotates the characters between 'Z' and 'a'.

Here's a test string for you: s := strings.NewReader("Lbh @ [\\]^_` { penpxrq gur pbqr!")

Here was my solution before I came here and realized I could just do -= 13:

func (r rot13Reader) Read(b []byte) (int, error) {
	n, err := r.r.Read(b)
	if err != nil {
		return n, err
	}

	for i := 0; i < n; i++ {
		if b[i] < 'A' || b[i] > 'z' || b[i] > 'Z' && b[i] < 'a' {
			continue
		}

		b[i] += 13
		if b[i] > 'z' || b[i] < 'a' && b[i] > 'Z' {
			b[i] -= 26
		}
	}

	return n, nil
}

@woto

woto commented Feb 27, 2018 •

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rR *rot13Reader) Read(b []byte) (n int, err error) {
	n, err = rR.r.Read(b)
	for idx, char := range b {
		if char != ' ' {
			sign := 1
			if (char >= 'N' && char <= 'Z') ||
				(char >= 'n' && char <= 'z') {
				sign = sign * -1
			}
			b[idx] = char + byte(sign*13)
		}
	}
	return n, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr! ABCDEFGHIJKLM NOPQRSTUVWXYZ abcdefghijklm nopqrstuvwxyz")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)	
}

@ptagr

ptagr commented May 25, 2018 •

Copy link
Copy Markdown

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (pr rot13Reader) Read(bytes []byte) (n int, err error) {
	n, err = pr.r.Read(bytes)
	for i,_ := range bytes {
		if bytes[i] >= 97 && bytes[i] <= 122 {
			bytes[i] = byte((bytes[i] - 97 + 13) % 26 + 97)
		} else if bytes[i] >= 65 && bytes[i] <= 90 {
			bytes[i] = byte((bytes[i] - 65 + 13) % 26 + 65)
		}
	}
	return n,err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@justinpage

Copy link
Copy Markdown

Had some fun using maps and relying on byte conversion:

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (reader rot13Reader) Read(p []byte) (int, error) {
	n, err := reader.r.Read(p)

	if err == io.EOF {
		return 0, err
	}

	lookup := map[string]string{
		"N": "A", "O": "B", "P": "C", "Q": "D",
		"R": "E", "S": "F", "T": "G", "U": "H",
		"V": "I", "W": "J", "X": "K", "Y": "L",
		"Z": "M", "A": "N", "B": "O", "C": "P",
		"D": "Q", "E": "R", "F": "S", "G": "T",
		"H": "U", "I": "V", "J": "W", "K": "X",
		"L": "Y", "M": "Z", "n": "a", "o": "b",
		"p": "c", "q": "d", "r": "e", "s": "f",
		"t": "g", "u": "h", "v": "i", "w": "j",
		"x": "k", "y": "l", "z": "m", "a": "n",
		"b": "o", "c": "p", "d": "q", "e": "r",
		"f": "s", "g": "t", "h": "u", "i": "v",
		"j": "w", "k": "x", "l": "y", "m": "z",
	}

	for index := range p[:n] {
		code := lookup[string(p[index])]

		if code != "" {
			p[index] = []byte(code)[0]
		}
	}

	return len(p), nil
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@gothicx

gothicx commented Aug 14, 2018

Copy link
Copy Markdown
// Another version of rot13

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func rot13(b byte) byte {
	if b >= 'A' && b <= 'M' || b >= 'a' && b <= 'm' {
		return b + 13
	}
	if b > 'M' && b <= 'Z' || b > 'm' && b <= 'z' {
		return b - 13
	}
	return b
}

func (rot rot13Reader) Read(b []byte) (int, error) {
	n, err := rot.r.Read(b)
	
	for i := range b {
		b[i] = rot13(b[i])
	}

	return n, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@xtttttttttx

xtttttttttx commented Sep 10, 2018 •

Copy link
Copy Markdown

Use a switch to make the code clearer.

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rot rot13Reader) Read(b []byte) (int, error) {
	n, _ := rot.r.Read(b)
	for i := 0; i < n; i++ {
		switch {
		case b[i] + 13 > 'z':
			b[i] -= 13
		case b[i] > 'a':
			b[i] += 13
		case b[i] + 13 > 'Z':
			b[i] -= 13
		case b[i] > 'A':
			b[i] += 13
		}
	}
	return n, nil
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@kden416

kden416 commented Jan 19, 2019

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rot rot13Reader) Read(b []byte) (int, error) {
	ln, err := rot.r.Read(b)
	for i := 0; i < ln; i++ {
		switch {
		case b[i] >= 65 && b[i] <= 77:
			b[i] += 13
		case b[i] >= 78 && b[i] <= 90:
			b[i] -= 13
		case b[i] >= 97 && b[i] <= 109:
			b[i] += 13
		case b[i] >= 110 && b[i] <= 122:
			b[i] -= 13
		}
	}
	return ln, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@danx12

danx12 commented Mar 9, 2019 •

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rot rot13Reader) Read(b []byte) (int, error) {

	n, err := rot.r.Read(b)
	for i := range b {
		if b[i] >= 0x41 && b[i] <= 0x5a {
			b[i] = byte((int(b[i]) - 0x41 + 13 )% 26 + 0x41)
		} else if b[i] >= 0x61 && b[i] <= 0x7a {
			b[i] = byte((int(b[i]) - 0x61 + 13 )% 26 + 0x61)
		}
	}

	return n, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@metatronz

metatronz commented Sep 13, 2019 •

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rot rot13Reader) Read(p []byte) (n int, err error) {

	var rmap = map[byte]byte{65: 78, 66: 79, 67: 80, 68: 81, 69: 82, 70: 83,
		71: 84, 72: 85, 73: 86, 74: 87, 75: 88, 76: 89, 77: 90,
		78: 65, 79: 66, 80: 67, 81: 68, 82: 69, 83: 70, 84: 71,
		85: 72, 86: 73, 87: 74, 88: 75, 89: 76, 90: 77, 97: 110,
		98: 111, 99: 112, 100: 113, 101: 114, 102: 115, 103: 116,
		104: 117, 105: 118, 106: 119, 107: 120, 108: 121, 109: 122,
		110: 97, 111: 98, 112: 99, 113: 100, 114: 101, 115: 102, 116: 103,
		117: 104, 118: 105, 119: 106, 120: 107, 121: 108, 122: 109}
	if n, err = rot.r.Read(p); err == nil {
		for x, src := range p {
			if dst, ok := rmap[src]; ok {
				p[x] = dst
			}
		}
	}
	return
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@sometimesalready

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (r rot13Reader) Read(b []byte) (int, error){
	n, e := r.r.Read(b)
	for i:=0; i<n; i++ {
		b[i] = byte(rot13(rune(b[i])))
	}
	return n, e
}


func rot13(r rune) rune {
    if r >= 'a' && r <= 'z' {
        // Rotate lowercase letters 13 places.
        if r >= 'm' {
            return r - 13
        } else {
            return r + 13
        }
    } else if r >= 'A' && r <= 'Z' {
        // Rotate uppercase letters 13 places.
        if r >= 'M' {
            return r - 13
        } else {
            return r + 13
        }
    }
    // Do nothing.
    return r
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@Maximilan4

Maximilan4 commented Dec 11, 2019 •

Copy link
Copy Markdown
package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

func (reader rot13Reader) Read(p []byte) (int, error) {
    n, err := reader.r.Read(p)
    if err != nil {
        return n, err
    }

    for index := 0; index <= n-1; index++ {
        value := p[index]
        if value < 65 || value > 122 {
            continue
        }

        if (value > 77 && value < 90) || value > 109 {
            p[index] -= 13
        } else {
            p[index] += 13
        }
    }

    return n, err
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
}

@ur4nium235

Copy link
Copy Markdown

My solution

package main

import (
    "io"
    "os"
    "strings"
)

type rotReader struct {
	r io.Reader
}

func rotX(x byte, rot int) byte {
	if x >= 65 && x <= 90 {
		x = byte((int(x)-65+rot)%26 + 65)
	} else if x >= 97 && x <= 122 {
		x = byte((int(x)-97+rot)%26 + 97)
	}
	return x
}

func (rot rotReader) Read(b []byte) (int, error) {
	n, err := rot.r.Read(b)
	for i := range b {
		b[i] = rotX(b[i], 13)
	}
	return n, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rotReader{s}
	io.Copy(os.Stdout, &r)
}

Output:
You cracked the code!

@hjalte33

hjalte33 commented Feb 27, 2020 •

Copy link
Copy Markdown

Came up with this little approach. The idea is to just try first by adding 13 and if we missed and went past z then just undo by subtracting 26. Thought it was a fun alternative

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rot rot13Reader) Read(b []byte) (n int, err error) {
	n, err = rot.r.Read(b)
	if err != nil {
		return 0, err
	}
	for i := 0; i < n; i++ {
		b[i] += 13
		if b[i] > 'z' || (b[i] > 'Z' && b[i] < 'Z'+13) {
			b[i] -= 26
		}
	}
	return n, nil
}

func main() {
	s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@this-is-richard

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
	//"fmt"
)

type rot13Reader struct {
	r io.Reader
}

func (rot13 rot13Reader) Read(b []byte) (int, error) {
	n, err := rot13.r.Read(b)
	for i := 0; i < n; i++ {
		switch {
			case b[i] >= 65 && b[i] <= 90:
				if b[i] <= 77 { b[i] = b[i] + 13 } else { b[i] = b[i] - 13 }
			case b[i] >= 97 && b[i] <= 122:
				if b[i] <= 109 { b[i] = b[i] + 13 } else { b[i] = b[i] - 13 }
		}
    }
	return n, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@olehcambel

olehcambel commented Apr 14, 2020 •

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rot13 rot13Reader) Read(p []byte) (int, error) {
	input := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
	output := "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"

	n, err := rot13.r.Read(p)

	for i := 0; i < n; i++ {
		index := strings.Index(input, string(p[i]))

		if index != -1 {
			p[i] = output[index]
		}
	}

	return n, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@kaen98

kaen98 commented Apr 28, 2020

Copy link
Copy Markdown
package main

import (
	"io"
	"os"
	"strings"
)

const src string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
const des string = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"

type rot13Reader struct {
	r io.Reader
}

func (rot13 rot13Reader) Read(bytes []byte) (int, error) {
	len, err := rot13.r.Read(bytes)
	for i, v := range bytes {
		index := strings.IndexByte(src, v)
		if (index != -1) {
			bytes[i] = des[index]
		}
	}
	return len, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@hashlash

Copy link
Copy Markdown

https://gist.github.com/hashlash/63edd5ab69cafe6ef762023e1cacc7ef

package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

func (r13 rot13Reader) Read(b []byte) (int, error) {
    l, err := r13.r.Read(b)
    if err == nil {
        for i := range b {
            switch {
                case 'A' <= b[i] && b[i] <= 'Z':
                    b[i] = (b[i] - 'A' + 13) % 26 + 'A'
                case 'a' <= b[i] && b[i] <= 'z':
                    b[i] = (b[i] - 'a' + 13) % 26 + 'a'
            }
        }
    }
    return l, err
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
}

@KunalKumarSwift

KunalKumarSwift commented Sep 7, 2021 •

Copy link
Copy Markdown
func (r rot13Reader) Read(b []byte) (n int, err error) {
	// read incoming stream and get length and error
	n, err = r.r.Read(b)
	// iterate over that range and read individual byte element
	for i := 0; i < n; i++ {
		v := b[i]
		// check ascii codes and keep replacing in the original stream b
		if v >= 65 && v <= 77 {
			b[i] = v + 13
		}

		if v >= 78 && v <= 90 {
			b[i] = v - 13
		}

		if v >= 97 && v <= 109 {
			b[i] = v + 13
		}

		if v >= 110 && v <= 122 {
			b[i] = v - 13
		}
	}
        if err == io.EOF {
		return 0, err
	}
	return n, nil
}

@C-Canchola

C-Canchola commented Oct 3, 2021 •

Copy link
Copy Markdown

Saw this on wikipedia and wanted to see if I could implement the Read method using it:
$ # Map upper case A-Z to N-ZA-M and lower case a-z to n-za-m
$ tr 'A-Za-z' 'N-ZA-Mn-za-m' <<< "The Quick Brown Fox Jumps Over The Lazy Dog"
Gur Dhvpx Oebja Sbk Whzcf Bire Gur Ynml Qbt

My attempt:

package main

import (
	"bytes"
	"io"
	"os"
	"os/exec"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

// trRot returns a new byte slice by using the tr command on the originally provided byte slice.
func trRot(b []byte) ([]byte, error) {

	r13Buf := &bytes.Buffer{}

	cmd := exec.Command("tr", "A-Za-z", "N-ZA-Mn-za-m")
	cmd.Stdin, cmd.Stdout, cmd.Stderr = bytes.NewBuffer(b), r13Buf, os.Stderr

	if err := cmd.Run(); err != nil {
		return nil, err
	}

	return r13Buf.Bytes(), nil
}

func (rr rot13Reader) Read(b []byte) (int, error) {

	readBytes := make([]byte, len(b))

	n, err := rr.r.Read(readBytes)
	if err != nil {
		return n, err
	}

	r13Bytes, err := trRot(readBytes)
	if err != nil {
		return 0, err
	}

	return copy(b, r13Bytes), err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

@Spaider

Spaider commented Jun 7, 2022

Copy link
Copy Markdown

Hey, looks like almost nobody noticed that there's an exclamation mark at the end of the string :)

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (r13 rot13Reader) Read(p []byte) (int, error) {
	var n, err = r13.r.Read(p)

	for i := 0; i < n; i++ {
		var inp = p[i]
		if (inp >= 65 && inp <= 77) ||
			(inp >= 97 && inp <= 109) {
			p[i] = inp + 13
		} else if (inp >= 78 && inp <= 90) ||
			(inp >= 110 && inp <= 122) {
			p[i] = inp - 13
		}
	}

	return n, err
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment