diff --git a/Algorithms.Tests/Encoders/AutokeyEncoderTests.cs b/Algorithms.Tests/Encoders/AutokeyEncoderTests.cs
new file mode 100644
index 00000000..0613e1c6
--- /dev/null
+++ b/Algorithms.Tests/Encoders/AutokeyEncoderTests.cs
@@ -0,0 +1,26 @@
+using System;
+using Algorithms.Encoders;
+using NUnit.Framework;
+using NUnit.Framework.Internal;
+
+namespace Algorithms.Tests.Encoders
+{
+ public static class AutokeyEncoderTests
+ {
+ [Test]
+ public static void DecodedStringIsTheSame()
+ {
+ // Arrange
+ var plainText = "PLAINTEXT";
+ var keyword = "KEYWORD";
+ var encoder = new AutokeyEncorder();
+
+ // Act
+ var encoded = encoder.Encode(plainText, keyword);
+ var decoded = encoder.Decode(encoded, keyword);
+
+ // Assert
+ Assert.That(decoded, Is.EqualTo(plainText));
+ }
+ }
+}
diff --git a/Algorithms/Encoders/AutokeyEncorder.cs b/Algorithms/Encoders/AutokeyEncorder.cs
new file mode 100644
index 00000000..8dc13d37
--- /dev/null
+++ b/Algorithms/Encoders/AutokeyEncorder.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Globalization;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Algorithms.Encoders
+{
+ ///
+ /// Class for AutoKey encoding strings.
+ ///
+ public class AutokeyEncorder
+ {
+ ///
+ /// Autokey Cipher is a type of polyalphabetic cipher.
+ /// This works by choosing a key (a word or short phrase),
+ /// then you append the plaintext to itself to form a longer key.
+ ///
+ /// The string to be appended to the key.
+ /// The string to be appended to the plaintext.
+ /// The Autokey encoded string (All Uppercase).
+ public string Encode(string plainText, string keyword)
+ {
+ plainText = Regex.Replace(plainText.ToUpper(CultureInfo.InvariantCulture), "[^A-Z]", string.Empty);
+ keyword = keyword.ToUpper(CultureInfo.InvariantCulture);
+
+ keyword += plainText;
+
+ StringBuilder cipherText = new StringBuilder();
+
+ for(int i = 0; i < plainText.Length; i++)
+ {
+ char plainCharacter = plainText[i];
+ char keyCharacter = keyword[i];
+
+ int encryptedCharacter = (plainCharacter - 'A' + keyCharacter - 'A') % 26 + 'A';
+ cipherText.Append((char)encryptedCharacter);
+ }
+
+ return cipherText.ToString();
+ }
+
+ ///
+ /// Removed the key from the encoded string.
+ ///
+ /// The encoded string.
+ /// The key to be removed from the encoded string.
+ /// The plaintext (All Uppercase).
+ public string Decode(string cipherText, string keyword)
+ {
+ cipherText = Regex.Replace(cipherText.ToUpper(CultureInfo.InvariantCulture), "[^A-Z]", string.Empty);
+ keyword = keyword.ToUpper(CultureInfo.InvariantCulture);
+
+ StringBuilder plainText = new StringBuilder();
+ StringBuilder extendedKeyword = new StringBuilder(keyword);
+
+ for(int i = 0; i < cipherText.Length; i++)
+ {
+ char cipherCharacter = cipherText[i];
+ char keywordCharacter = extendedKeyword[i];
+
+ int decryptedCharacter = (cipherCharacter - 'A' - (keywordCharacter - 'A') + 26) % 26 + 'A';
+ plainText.Append((char)decryptedCharacter);
+ extendedKeyword.Append((char)decryptedCharacter);
+ }
+
+ return plainText.ToString();
+ }
+ }
+}
diff --git a/README.md b/README.md
index 198d2bd7..b9933f9f 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,7 @@ find more than one implementation for the same objective but using different alg
* [Soundex](./Algorithms/Encoders/SoundexEncoder.cs)
* [Feistel](./Algorithms/Encoders/FeistelCipher.cs)
* [Blowfish](./Algorithms/Encoders/BlowfishEncoder.cs)
+ * [Autokey](./Algorithms/Encoders/AutokeyEncoder.cs)
* [Graph](./Algorithms/Graph)
* [Minimum Spanning Tree](./Algorithms/Graph/MinimumSpanningTree)
* [Prim's Algorithm (Adjacency Matrix)](./Algorithms/Graph/MinimumSpanningTree/PrimMatrix.cs)