Skip to content

Instantly share code, notes, and snippets.

@martani
Created April 27, 2011 15:11
Show Gist options
  • Save martani/944422 to your computer and use it in GitHub Desktop.
Save martani/944422 to your computer and use it in GitHub Desktop.
A simple Vigenere Decoder
//MARTANI Fakhrou 2011
//Vigenere Decoder
//http://martani.net
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace codebook
{
class Program
{
static void Main(string[] args)
{
string VigenereCryptogram = @"KQOWEFVJPUJUUNUKGLMEKJINMWUXFQMKJBGWRLFNFGHUDWUUMBSVLPSNCMUEKQCTESWREEKOYSSIWCTUAXYOTAPXPLWPNTCGOJBGFQHTDWXIZAYGFFNS
XCSEYNCTSSPNTUJNYTGGWZGRWUUNEJUUQEAPYMEKQHUIDUXFPGUYTSMTFFSHNUOCZGMRUWEYTRGKMEEDCTVRECFBDJQCUSWVBPNLGOYLSKMTEFVJJTWWM
FMWPNMEMTMHRSPXFSSKFFSTNUOCZGMDOEOYEEKCPJRGPMURSKHFRSEIUEVGOYCWXIZAYGOSAANYDOEOYJLWUNHAMEBFELXYVLWNOJNSIOFRWUCCESWKVI
DGMUCGOCRUWGNMAAFFVNSIUDEKQHCEUCPFCMPVSUDGAVEMNYMAMVLFMAOYFNTQCUAFVFJNXKLNEIWCWODCCULWRIFTWGMUSWOVMATNYBUHTCOCWFYTNMG
YTQMKBBNLGFBTWOJFTWGNTEJKNEEDCLDHWTVBUVGFBIJGYYIDGMVRDGMPLSWGJLAGOEEKJOFEKNYNOLRIVRWVUHEIWUURWGMUTJCDBNKGMBIDGMEEYGUO
TDGGQEUJYOTVGGBRUJYS";
int keyLen = 5;
Dictionary<char, double> frequencies;
List<char> keyChars = new List<char>();
VigenereCryptogram.Replace(" ", "").Replace("\n", "").Replace("\r", "");
List<string> substitutionTexts = SplitTextWithKeyLen(VigenereCryptogram, keyLen);
foreach (string caesarCryptogram in substitutionTexts)
{
Console.WriteLine(caesarCryptogram);
Console.WriteLine(string.Format("Length: {0}", caesarCryptogram.Length));
frequencies = AnalyseFrequency(caesarCryptogram);
double maxFreq = frequencies.Values.Max();
char maxChar = frequencies.Keys.Where(c => frequencies[c] == maxFreq).FirstOrDefault();
//'E' is the maxChar
Console.WriteLine(string.Format("E is probably: {0} - {1}", maxChar, maxFreq));
Console.WriteLine(string.Format("Key would be: {0}", (char) (maxChar - 'e' + 'A')));
keyChars.Add((char)(maxChar - 'e' + 'A'));
foreach (var item in frequencies)
{
Console.WriteLine(string.Format("{0}: {1:0.00}", item.Key, item.Value));
}
Console.WriteLine("******************************");
Console.WriteLine("");
}
string VigenereKEY = "";
foreach (char c in keyChars)
{
VigenereKEY += c;
}
Console.WriteLine("Key found: {0}", VigenereKEY);
Console.WriteLine(DecipherVeginere(VigenereCryptogram, VigenereKEY));
Console.ReadLine();
}
static List<string> SplitTextWithKeyLen(string text, int keyLen)
{
List<string> result = new List<string>();
StringBuilder[] sb = new StringBuilder[keyLen];
for (int i = 0; i < keyLen; i++)
{
sb[i] = new StringBuilder();
}
for (int i = 0; i < text.Length; i++)
{
sb[i % keyLen].Append(text[i]);
}
foreach (var item in sb)
{
result.Add(item.ToString());
}
return result;
}
static Dictionary<char, double> AnalyseFrequency(string text)
{
if (text == null)
return null;
Dictionary<char, double> frequencies = new Dictionary<char, double>();
int textLength = text.Length;
for (int i = 0; i < textLength; i++)
{
char c = text[i];
char key = '#';
//ignore chars that are not letters
if ((c >= 'a' && c <= 'z'))
key = c;
if (c >= 'A' && c <= 'Z')
key = (char)(c + 'a' - 'A');
if (frequencies.Keys.Contains(key))
frequencies[key] = frequencies[key] + 1;
else
frequencies[key] = 1;
}
//cannot enumerate throught the dictionnay keys directly.
List<char> keys = frequencies.Keys.ToList();
foreach (char c in keys)
{
frequencies[c] /= textLength;
}
return frequencies;
}
static string DecipherVeginere(string text, string key)
{
StringBuilder result = new StringBuilder();
int keyLength = key.Length;
int diff;
char decoded;
for (int i = 0; i < text.Length; i++)
{
diff = text[i] - key[i%keyLength];
//diff should never be more than 25 or less than -25
if(diff < 0)
diff += 26;
decoded = (char)(diff + 'a') ;
result.Append(decoded);
}
return result.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment