RosettaCodeData/Task/Caesar-cipher/Go/caesar-cipher-1.go

60 lines
1.4 KiB
Go

package main
import (
"fmt"
"strings"
)
type ckey struct {
enc, dec func(rune) rune
}
func newCaesar(k int) (*ckey, bool) {
if k < 1 || k > 25 {
return nil, false
}
rk := rune(k)
return &ckey{
enc: func(c rune) rune {
if c >= 'a' && c <= 'z'-rk || c >= 'A' && c <= 'Z'-rk {
return c + rk
} else if c > 'z'-rk && c <= 'z' || c > 'Z'-rk && c <= 'Z' {
return c + rk - 26
}
return c
},
dec: func(c rune) rune {
if c >= 'a'+rk && c <= 'z' || c >= 'A'+rk && c <= 'Z' {
return c - rk
} else if c >= 'a' && c < 'a'+rk || c >= 'A' && c < 'A'+rk {
return c - rk + 26
}
return c
},
}, true
}
func (ck ckey) encipher(pt string) string {
return strings.Map(ck.enc, pt)
}
func (ck ckey) decipher(ct string) string {
return strings.Map(ck.dec, ct)
}
func main() {
pt := "The five boxing wizards jump quickly"
fmt.Println("Plaintext:", pt)
for _, key := range []int{0, 1, 7, 25, 26} {
ck, ok := newCaesar(key)
if !ok {
fmt.Println("Key", key, "invalid")
continue
}
ct := ck.encipher(pt)
fmt.Println("Key", key)
fmt.Println(" Enciphered:", ct)
fmt.Println(" Deciphered:", ck.decipher(ct))
}
}