Skip to content

Commit 3cd6860

Browse files
committed
Add Autokey encoder
1 parent 329fc50 commit 3cd6860

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using Algorithms.Encoders;
3+
using NUnit.Framework;
4+
using NUnit.Framework.Internal;
5+
6+
namespace Algorithms.Tests.Encoders
7+
{
8+
public class AutokeyEncoderTests
9+
{
10+
[Test]
11+
public static void DecodedStringIsTheSame()
12+
{
13+
// Arrange
14+
var plainText = "PLAINTEXT";
15+
var keyword = "KEYWORD";
16+
var encoder = new AutokeyEncorder();
17+
18+
// Act
19+
var encoded = encoder.Encode(plainText, keyword);
20+
var decoded = encoder.Decode(encoded, keyword);
21+
22+
// Assert
23+
Assert.That(decoded, Is.EqualTo(plainText));
24+
}
25+
}
26+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Text;
3+
using System.Text.RegularExpressions;
4+
5+
namespace Algorithms.Encoders
6+
{
7+
/// <summary>
8+
/// Class for AutoKey encoding strings.
9+
/// </summary>
10+
public class AutokeyEncorder
11+
{
12+
/// <summary>
13+
/// Autokey Cipher is a type of polyalphabetic cipher.
14+
/// This works by choosing a key (a word or short phrase),
15+
/// then you append the plaintext to itself to form a longer key.
16+
/// </summary>
17+
/// <param name="plainText">The string to be appended to the key.</param>
18+
/// <param name="keyword">The string to be appended to the plaintext.</param>
19+
/// <returns>The Autokey encoded string (All Uppercase).</returns>
20+
public string Encode(string plainText, string keyword)
21+
{
22+
plainText = Regex.Replace(plainText.ToUpper(), "[^A-Z]", string.Empty);
23+
keyword = keyword.ToUpper();
24+
25+
keyword += plainText;
26+
27+
StringBuilder cipherText = new StringBuilder();
28+
29+
for(int i = 0; i < plainText.Length; i++)
30+
{
31+
char plainCharacter = plainText[i];
32+
char keyCharacter = keyword[i];
33+
34+
int encryptedCharacter = (plainCharacter - 'A' + keyCharacter - 'A') % 26 + 'A';
35+
cipherText.Append((char)encryptedCharacter);
36+
}
37+
38+
return cipherText.ToString();
39+
}
40+
41+
/// <summary>
42+
/// Removed the key from the encoded string.
43+
/// </summary>
44+
/// <param name="cipherText">The encoded string.</param>
45+
/// <param name="keyword">The key to be removed from the encoded string.</param>
46+
/// <returns>The plaintext (All Uppercase).</returns>
47+
public string Decode(string cipherText, string keyword)
48+
{
49+
cipherText = Regex.Replace(cipherText.ToUpper(), "[^A-Z]", string.Empty);
50+
keyword = keyword.ToUpper();
51+
52+
StringBuilder plainText = new StringBuilder();
53+
StringBuilder extendedKeyword = new StringBuilder(keyword);
54+
55+
for(int i = 0; i < cipherText.Length; i++)
56+
{
57+
char cipherCharacter = cipherText[i];
58+
char keywordCharacter = extendedKeyword[i];
59+
60+
int decryptedCharacter = (cipherCharacter - 'A' - (keywordCharacter - 'A') + 26) % 26 + 'A';
61+
plainText.Append((char)decryptedCharacter);
62+
extendedKeyword.Append((char)decryptedCharacter);
63+
}
64+
65+
return plainText.ToString();
66+
}
67+
}
68+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ find more than one implementation for the same objective but using different alg
4141
* [Soundex](./Algorithms/Encoders/SoundexEncoder.cs)
4242
* [Feistel](./Algorithms/Encoders/FeistelCipher.cs)
4343
* [Blowfish](./Algorithms/Encoders/BlowfishEncoder.cs)
44+
* [Autokey](./Algorithms/Encoders/AutokeyEncoder.cs)
4445
* [Graph](./Algorithms/Graph)
4546
* [Minimum Spanning Tree](./Algorithms/Graph/MinimumSpanningTree)
4647
* [Prim's Algorithm (Adjacency Matrix)](./Algorithms/Graph/MinimumSpanningTree/PrimMatrix.cs)

0 commit comments

Comments
 (0)