-
-
Save flc/6439105 to your computer and use it in GitHub Desktop.
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) | |
} |
hjhee
commented
Jul 27, 2017
•
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)
}
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)
}
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)
}
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
}
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)
}
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)
}
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)
}
// 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)
}
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)
}
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)
}
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)
}
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)
}
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)
}
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)
}
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!
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)
}
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)
}
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)
}
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)
}
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)
}
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
}
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)
}
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)
}