Example #1
0
        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}");
        }
Example #2
0
        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);
        }
Example #3
0
        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("------------------");
        }
Example #4
0
        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);
        }