public void Challenge4_Solution() { var inputFile = new StreamReader("Assets/inputForChallenge4.txt"); var results = new Dictionary <string, double>(); while (!inputFile.EndOfStream) { var encryptedLine = Converter.FromHexStringToByteArray(inputFile.ReadLine().Trim()); var key = SingleByteXorCipher.FindSingleByteKey(encryptedLine); var decryptedText = SingleByteXorCipher.Decrypt(encryptedLine, key); var score = SingleByteXorCipher.ScoreAccordingToEnglishLetterFrequency(Encoding.Default.GetBytes(decryptedText)); results.Add(decryptedText, score); } var hiddenMessage = results.OrderByDescending(x => x.Value).First(); Assert.AreEqual("Now that the party is jumping\n", hiddenMessage.Key); Console.WriteLine($"Score:{hiddenMessage.Value}"); }
public void Challenge3_Solution() { var inputByteArray = Converter.FromHexStringToByteArray(_hexStringInput); var key = SingleByteXorCipher.FindSingleByteKey(inputByteArray); Assert.AreEqual('X', Convert.ToChar(key)); var decryptedText = SingleByteXorCipher.Decrypt(inputByteArray, key); Assert.AreEqual("Cooking MC's like a pound of bacon", decryptedText); }
public void SingleByteXorCipher_Test() { // assign string input = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"; string key = null; string expected = "Cooking MC's like a pound of bacon"; // execute string actual = SingleByteXorCipher.Decrypt(input, out key); // assert, ignore case Assert.IsNotNull(actual); Assert.IsNotNull(key); Assert.AreEqual(expected, actual, true); System.Diagnostics.Debug.WriteLine("------------------"); System.Diagnostics.Debug.WriteLine(actual); System.Diagnostics.Debug.WriteLine("------------------"); }
public void Challenge6_Solution() { var inputFile = new StreamReader("Assets/inputForChallenge6.txt").ReadToEnd(); var inputByteArray = Convert.FromBase64String(inputFile); // Find key size var keySizeEditDistanceList = new Dictionary <byte, double>(); for (byte candidateKeySize = 2; candidateKeySize < 41; candidateKeySize++) { var distanceList = new List <int>(); for (int currentIndex = 0; currentIndex < inputByteArray.Length; currentIndex = currentIndex + candidateKeySize) { var first = inputByteArray.Skip(currentIndex).Take(candidateKeySize).ToArray(); var second = inputByteArray.Skip(currentIndex + candidateKeySize).Take(candidateKeySize).ToArray(); var distance = HammingDistance.Calculate(first, second); distanceList.Add(distance); } var avgDistance = distanceList.Average(); keySizeEditDistanceList.Add(candidateKeySize, avgDistance / candidateKeySize); } var keySize = keySizeEditDistanceList.OrderBy(x => x.Value).First().Key; Assert.AreEqual(29, keySize); // Transpose byte array according to the key size var blockList = new List <byte[]>(); for (int i = 0; i < inputByteArray.Length; i = i + keySize) { blockList.Add(inputByteArray.Skip(i).Take(keySize).ToArray()); } var lastBlock = blockList.Last(); if (lastBlock.Length < keySize) { var expandedLast = new byte[keySize]; for (int i = 0; i < lastBlock.Length; i++) { expandedLast[i] = lastBlock[i]; } blockList.RemoveAt(blockList.Count - 1); blockList.Add(expandedLast); } var transposedBlockList = new List <byte[]>(); for (int i = 0; i < keySize; i++) { var transposedBlockArray = new byte[blockList.Count]; for (int j = 0; j < blockList.Count; j++) { transposedBlockArray[j] = blockList[j][i]; } transposedBlockList.Add(transposedBlockArray); } // Use single byte xor cipher solution for each block to find the repeating key var keyList = new List <byte>(); foreach (var block in transposedBlockList) { var minScore = 0d; byte selectedByteCode = 32; for (byte byteCode = 32; byteCode < 127; byteCode++) // <-- Brute force search for the correct character { var output = Xor.Apply(block, byteCode); var score = SingleByteXorCipher.ScoreAccordingToEnglishLetterFrequency(output); if (score > minScore) { minScore = score; selectedByteCode = byteCode; } } //Console.WriteLine($"minScore: {minScore} selectedByteCode:{Convert.ToChar(selectedByteCode)}"); keyList.Add(selectedByteCode); } var keyByteArray = keyList.ToArray(); Assert.AreEqual("Terminator X: Bring the noise", Encoding.Default.GetString(keyByteArray)); // Decrypt text var decryptedByteArray = new byte[inputByteArray.Length]; for (int i = 0; i < inputByteArray.Length; i++) { decryptedByteArray[i] = (byte)(inputByteArray[i] ^ keyByteArray[i % keySize]); } var decryptedText = Encoding.UTF8.GetString(decryptedByteArray); Console.WriteLine(decryptedText); }