Content-Length: 637116 | pFad | http://github.com/TheAlgorithms/Go/commit/c5173f35db0b90d48a7286c3124c7da53a53efcc

ED Add railfence cipher (#715) · TheAlgorithms/Go@c5173f3 · GitHub
Skip to content

Commit c5173f3

Browse files
Add railfence cipher (#715)
* added rail fence cipher implementation * updated readme * fixed typo --------- Co-authored-by: Rak Laptudirm <rak@laptudirm.com>
1 parent 0d0b97a commit c5173f3

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,19 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
11991199
2. [`Encrypt`](./cipher/xor/xor.go#L10): Encrypt encrypts with Xor encryption after converting each character to byte The returned value might not be readable because there is no guarantee which is within the ASCII range If using other type such as string, []int, or some other types, add the statements for converting the type to []byte.
12001200
3. [`FuzzXOR`](./cipher/xor/xor_test.go#L108): No description provided.
12011201

1202+
---
1203+
</details>
1204+
1205+
##### Package rail fence is a classical type of transposition cipher ref : https://en.wikipedia.org/wiki/Rail_fence_cipher
1206+
1207+
---
1208+
##### Functions:
1209+
1210+
1. [`Encrypt`](.cipher/railfence/railfence.go#L7): Encrypt encrypts a message using rail fence cipher
1211+
2. [`Decrypt`](.cipher/railfence/railfence.go#L44): decrypt decrypts a message using rail fence cipher
1212+
3. [`TestEncrypt`](.cipher/railfence/railfence_test.go#L7) Test function for Encrypt
1213+
4. [`TestDecrypt`](.cipher/railfence/railfence_test.go#L50) Test function for Decrypt
1214+
12021215
---
12031216
</details>
12041217
<!--- GODOCMD END --->

cipher/railfence/railfence.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package railfence
2+
3+
import (
4+
"strings"
5+
)
6+
7+
func Encrypt(text string, rails int) string {
8+
if rails == 1 {
9+
return text
10+
}
11+
12+
// Create a matrix for the rail fence pattern
13+
matrix := make([][]rune, rails)
14+
for i := range matrix {
15+
matrix[i] = make([]rune, len(text))
16+
}
17+
18+
// Fill the matrix
19+
dirDown := false
20+
row, col := 0, 0
21+
for _, char := range text {
22+
if row == 0 || row == rails-1 {
23+
dirDown = !dirDown
24+
}
25+
matrix[row][col] = char
26+
col++
27+
if dirDown {
28+
row++
29+
} else {
30+
row--
31+
}
32+
}
33+
var result strings.Builder
34+
for _, line := range matrix {
35+
for _, char := range line {
36+
if char != 0 {
37+
result.WriteRune(char)
38+
}
39+
}
40+
}
41+
42+
return result.String()
43+
}
44+
func Decrypt(cipherText string, rails int) string {
45+
if rails == 1 || rails >= len(cipherText) {
46+
return cipherText
47+
}
48+
49+
// Placeholder for the decrypted message
50+
decrypted := make([]rune, len(cipherText))
51+
52+
// Calculate the zigzag pattern and place characters accordingly
53+
index := 0
54+
for rail := 0; rail < rails; rail++ {
55+
position := rail
56+
down := true // Direction flag
57+
for position < len(cipherText) {
58+
decrypted[position] = rune(cipherText[index])
59+
index++
60+
61+
// Determine the next position based on the current rail and direction
62+
if rail == 0 || rail == rails-1 {
63+
position += 2 * (rails - 1)
64+
} else if down {
65+
position += 2 * (rails - 1 - rail)
66+
down = false
67+
} else {
68+
position += 2 * rail
69+
down = true
70+
}
71+
}
72+
}
73+
74+
return string(decrypted)
75+
}

cipher/railfence/railfence_test.go

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package railfence
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestEncrypt(t *testing.T) {
8+
var railFenceTestData = []struct {
9+
description string
10+
input string
11+
rails int
12+
expected string
13+
}{
14+
{
15+
"Encrypt with 2 rails",
16+
"hello",
17+
2,
18+
"hloel",
19+
},
20+
{
21+
"Encrypt with 3 rails",
22+
"hello world",
23+
3,
24+
"horel ollwd",
25+
},
26+
{
27+
"Encrypt with edge case: 1 rail",
28+
"hello",
29+
1,
30+
"hello",
31+
},
32+
{
33+
"Encrypt with more rails than letters",
34+
"hi",
35+
100,
36+
"hi",
37+
},
38+
}
39+
40+
for _, test := range railFenceTestData {
41+
t.Run(test.description, func(t *testing.T) {
42+
actual := Encrypt(test.input, test.rails)
43+
if actual != test.expected {
44+
t.Errorf("FAIL: %s - Encrypt(%s, %d) = %s, want %s", test.description, test.input, test.rails, actual, test.expected)
45+
}
46+
})
47+
}
48+
}
49+
50+
func TestDecrypt(t *testing.T) {
51+
var railFenceTestData = []struct {
52+
description string
53+
input string
54+
rails int
55+
expected string
56+
}{
57+
{
58+
"Decrypt with 2 rails",
59+
"hloel",
60+
2,
61+
"hello",
62+
},
63+
{
64+
"Decrypt with 3 rails",
65+
"ho l lewrdlo",
66+
3,
67+
"hld olle wor",
68+
},
69+
{
70+
"Decrypt with edge case: 1 rail",
71+
"hello",
72+
1,
73+
"hello",
74+
},
75+
{
76+
"Decrypt with more rails than letters",
77+
"hi",
78+
100,
79+
"hi",
80+
},
81+
}
82+
83+
for _, test := range railFenceTestData {
84+
t.Run(test.description, func(t *testing.T) {
85+
actual := Decrypt(test.input, test.rails)
86+
if actual != test.expected {
87+
t.Errorf("FAIL: %s - Decrypt(%s, %d) = %s, want %s", test.description, test.input, test.rails, actual, test.expected)
88+
}
89+
})
90+
}
91+
}

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/TheAlgorithms/Go/commit/c5173f35db0b90d48a7286c3124c7da53a53efcc

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy