Skip to content

Commit 736a23e

Browse files
authored
Add lacked tests for caesar cipher (#261)
* add lacked processing fix package name typo(ceaser=>caesar) update package structure for testing * add tests cases(coverage: 64.7%=>100.0%) fix misspelled words
1 parent 5aaade5 commit 736a23e

File tree

2 files changed

+176
-88
lines changed

2 files changed

+176
-88
lines changed

ciphers/caesar/CaesarCipher.go

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,38 @@
1-
package ceaser
2-
3-
import (
4-
"bytes"
5-
"flag"
6-
"fmt"
7-
"strings"
8-
)
9-
10-
func main() {
11-
cipherKey := flag.Int("c", 0, "Cipher shift amount (-26 - 26)")
12-
input := flag.String("i", "", "Input")
13-
flag.Parse()
14-
15-
if *cipherKey > 26 || *cipherKey < -26 {
16-
flag.PrintDefaults()
17-
} else {
18-
fmt.Println(caesarCipher(*input, *cipherKey))
19-
}
20-
1+
// Package caesar is the shift cipher
2+
// ref: https://en.wikipedia.org/wiki/Caesar_cipher
3+
package caesar
4+
5+
// Caesar is struct for Caesar cipher
6+
type Caesar struct {
7+
}
8+
9+
// NewCaesar returns a pointer to object of Caesar
10+
func NewCaesar() *Caesar {
11+
return &Caesar{}
2112
}
22-
23-
func caesarCipher(input string, key int) string {
24-
var outputBuffer bytes.Buffer
25-
for _, r := range strings.ToLower(input) {
13+
14+
// Encrypt encrypts by right shift of "key" each character of "input"
15+
func (c Caesar) Encrypt(input string, key int) string {
16+
// if key is negative value,
17+
// updates "key" the number which congruents to "key" modulo 26
18+
key = (key%26 + 26) % 26
19+
20+
outputBuffer := []byte{}
21+
for _, r := range input {
2622
newByte := byte(r)
27-
28-
if newByte >= 'a' && newByte <= 'z' {
29-
newByte += byte(key)
30-
31-
if newByte > 'z' {
32-
newByte -= 26
33-
} else if newByte < 'a' {
34-
newByte += 26
35-
}
23+
if 'A' <= newByte && newByte <= 'Z' {
24+
outputBuffer = append(outputBuffer, byte(int('A')+int(int(newByte-'A')+key)%26))
25+
} else if 'a' <= newByte && newByte <= 'z' {
26+
outputBuffer = append(outputBuffer, byte(int('a')+int(int(newByte-'a')+key)%26))
27+
} else {
28+
outputBuffer = append(outputBuffer, newByte)
3629
}
37-
38-
outputBuffer.WriteString(string(newByte))
3930
}
40-
return outputBuffer.String()
41-
}
31+
return string(outputBuffer)
32+
}
33+
34+
// Decrypt decrypts by left shift of "key" each character of "input"
35+
func (c Caesar) Decrypt(input string, key int) string {
36+
// left shift of "key" is same as right shift of 26-"key"
37+
return c.Encrypt(input, 26-key)
38+
}

ciphers/caesar/caesar_test.go

Lines changed: 142 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,135 @@
1-
package ceaser
1+
package caesar_test
22

33
import (
4+
"TheAlgorithms/Go/ciphers/caesar"
5+
"fmt"
46
"testing"
57
)
68

7-
var caesarTestData = []struct {
8-
description string
9-
input string
10-
key int
11-
expected string
12-
}{
13-
{
14-
"Basic caesar encryption with letter 'a'",
15-
"a",
16-
3,
17-
"d",
18-
},
19-
{
20-
"Basic caesar encryption wrap around alphabet on letter 'z'",
21-
"z",
22-
3,
23-
"c",
24-
},
25-
{
26-
"Encrypt a simple string with ceasar encryiption",
27-
"hello",
28-
3,
29-
"khoor",
30-
},
31-
{
32-
"Encrypt a simple string with key 13",
33-
"hello",
34-
13,
35-
"uryyb",
36-
},
37-
{
38-
"Encrypt a simple string with key -13",
39-
"hello",
40-
-13,
41-
"uryyb",
42-
},
43-
{
44-
"With key of 26 output should be the same as the input",
45-
"no change",
46-
26,
47-
"no change",
48-
},
49-
{
50-
"Encrpyt sentence with key 10",
51-
"the quick brown fox jumps over the lazy dog.",
52-
10,
53-
"dro aesmu lbygx pyh tewzc yfob dro vkji nyq.",
54-
},
9+
var c *caesar.Caesar = caesar.NewCaesar()
10+
11+
func TestEncrypt(t *testing.T) {
12+
var caesarTestData = []struct {
13+
description string
14+
input string
15+
key int
16+
expected string
17+
}{
18+
{
19+
"Basic caesar encryption with letter 'a'",
20+
"a",
21+
3,
22+
"d",
23+
},
24+
{
25+
"Basic caesar encryption wrap around alphabet on letter 'z'",
26+
"z",
27+
3,
28+
"c",
29+
},
30+
{
31+
"Encrypt a simple string with caesar encryiption",
32+
"hello",
33+
3,
34+
"khoor",
35+
},
36+
{
37+
"Encrypt a simple string with key 13",
38+
"hello",
39+
13,
40+
"uryyb",
41+
},
42+
{
43+
"Encrypt a simple string with key -13",
44+
"hello",
45+
-13,
46+
"uryyb",
47+
},
48+
{
49+
"With key of 26 output should be the same as the input",
50+
"no change",
51+
26,
52+
"no change",
53+
},
54+
{
55+
"Encrypt sentence with key 10",
56+
"the quick brown fox jumps over the lazy dog.",
57+
10,
58+
"dro aesmu lbygx pyh tewzc yfob dro vkji nyq.",
59+
},
60+
{
61+
"Encrypt sentence with key 10",
62+
"The Quick Brown Fox Jumps over the Lazy Dog.",
63+
10,
64+
"Dro Aesmu Lbygx Pyh Tewzc yfob dro Vkji Nyq.",
65+
},
66+
}
67+
for _, test := range caesarTestData {
68+
t.Run(test.description, func(t *testing.T) {
69+
actual := c.Encrypt(test.input, test.key)
70+
if actual != test.expected {
71+
t.Logf("FAIL: %s", test.description)
72+
t.Fatalf("With input string '%s' and key '%d' was expecting '%s' but actual was '%s'",
73+
test.input, test.key, test.expected, actual)
74+
}
75+
})
76+
}
5577
}
5678

57-
func TestCeasarCipher(t *testing.T) {
79+
func TestDecrypt(t *testing.T) {
80+
var caesarTestData = []struct {
81+
description string
82+
input string
83+
key int
84+
expected string
85+
}{
86+
{
87+
"Basic caesar decryption with letter 'a'",
88+
"a",
89+
3,
90+
"x",
91+
},
92+
{
93+
"Basic caesar decryption wrap around alphabet on letter 'z'",
94+
"z",
95+
3,
96+
"w",
97+
},
98+
{
99+
"Decrypt a simple string with caesar encryiption",
100+
"hello",
101+
3,
102+
"ebiil",
103+
},
104+
{
105+
"Decrypt a simple string with key 13",
106+
"hello",
107+
13,
108+
"uryyb",
109+
},
110+
{
111+
"Decrypt a simple string with key -13",
112+
"hello",
113+
-13,
114+
"uryyb",
115+
},
116+
{
117+
"With key of 26 output should be the same as the input",
118+
"no change",
119+
26,
120+
"no change",
121+
},
122+
{
123+
"Decrypt sentence with key 10",
124+
"Dro Aesmu Lbygx Pyh Tewzc yfob dro Vkji Nyq.",
125+
10,
126+
"The Quick Brown Fox Jumps over the Lazy Dog.",
127+
},
128+
}
129+
58130
for _, test := range caesarTestData {
59131
t.Run(test.description, func(t *testing.T) {
60-
actual := caesarCipher(test.input, test.key)
132+
actual := c.Decrypt(test.input, test.key)
61133
if actual != test.expected {
62134
t.Logf("FAIL: %s", test.description)
63135
t.Fatalf("With input string '%s' and key '%d' was expecting '%s' but actual was '%s'",
@@ -66,3 +138,22 @@ func TestCeasarCipher(t *testing.T) {
66138
})
67139
}
68140
}
141+
142+
func ExampleNewCaesar() {
143+
const (
144+
key = 10
145+
input = "The Quick Brown Fox Jumps over the Lazy Dog."
146+
)
147+
148+
c := caesar.NewCaesar()
149+
150+
encryptedText := c.Encrypt(input, key)
151+
fmt.Printf("Encrypt=> key: %d, input: %s, encryptedText: %s\n", key, input, encryptedText)
152+
153+
decryptedText := c.Decrypt(encryptedText, key)
154+
fmt.Printf("Decrypt=> key: %d, input: %s, decryptedText: %s\n", key, encryptedText, decryptedText)
155+
156+
// Output:
157+
// Encrypt=> key: 10, input: The Quick Brown Fox Jumps over the Lazy Dog., encryptedText: Dro Aesmu Lbygx Pyh Tewzc yfob dro Vkji Nyq.
158+
// Decrypt=> key: 10, input: Dro Aesmu Lbygx Pyh Tewzc yfob dro Vkji Nyq., decryptedText: The Quick Brown Fox Jumps over the Lazy Dog.
159+
}

0 commit comments

Comments
 (0)