-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathRail-Fence-Cipher.linq
More file actions
35 lines (25 loc) · 916 Bytes
/
Rail-Fence-Cipher.linq
File metadata and controls
35 lines (25 loc) · 916 Bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<Query Kind="Program" />
void Main()
{
var cipher = new RailFenceCipher(3);
string result = cipher.Encode("Testing");
result.Dump("Ciphered text");
string original = cipher.Decode(result);
original.Dump("Unciphered text");
}
public class RailFenceCipher
{
internal readonly int _rails;
public RailFenceCipher(int rails) => _rails = --rails;
internal int GetRow(int i) => _rails - Math.Abs(i % (2 * _rails) - _rails);
internal IEnumerable<T> ZigZagIndex<T>(IEnumerable<T> seq) => seq
.Select((c, i) => (c, r: GetRow(i)))
.GroupBy(v => v.r)
.SelectMany(v => v.Select(vc => vc.c));
public string Encode(string input) => string.Join("", ZigZagIndex(input));
public string Decode(string input) =>
ZigZagIndex(Enumerable.Range(0, input.Length))
.Zip(input, (f, s) => (i: f, c: s))
.OrderBy(v => v.i)
.Aggregate(new StringBuilder(), (sb, v) => sb.Append(v.c), sb => sb.ToString());
}