Beispiel #1
0
        static void DebugGetFactoredKeyLengthWeightings()
        {
            Console.Write("Text> ");
            string text = Console.ReadLine().ToUpper();

            Console.Write("Discard single occurences (1/0)?> ");
            bool discardSingle = int.Parse(Console.ReadLine()) != 0;

            Repetition[]          repetitions         = Repetition.GetTextRepetitions(text);
            Dictionary <int, int> keyLengthWeightings = KeyLengthDeduction.GetKeyLengthWeights(repetitions, discardSingle);
            Dictionary <int, int> factoredWeightings  = KeyLengthDeduction.GetFactoredKeyLengthWeights(keyLengthWeightings);

            foreach (int factoredkeyLength in factoredWeightings.Keys)
            {
                Console.WriteLine($"{factoredkeyLength} : {factoredWeightings[factoredkeyLength]}");
            }

            Console.WriteLine();
            Console.Write("Get Top x Results> ");
            int count = int.Parse(Console.ReadLine());

            Dictionary <int, int> topResults = ProgramMath.GetTopDictionaryKeysByValue(factoredWeightings, count);

            foreach (int topResult in topResults.Keys)
            {
                Console.WriteLine($"{topResult} : {topResults[topResult]}");
            }
        }
Beispiel #2
0
        static void DebugListActivePossibilities()
        {
            Console.Write("Range> ");

            int range = int.Parse(Console.ReadLine());

            List <int> input = new List <int>();

            for (int i = 0; i < range; i++)
            {
                input.Add(i);
            }

            List <List <int> > possibilities = ProgramMath.GetListActivePossibilities(input);

            foreach (List <int> possibility in possibilities)
            {
                foreach (int n in possibility)
                {
                    Console.Write(n.ToString() + ' ');
                }

                Console.WriteLine();
            }
        }
Beispiel #3
0
        static int KeyLengthSelection(string text)
        {
            Console.Write("Discard single-occurence key lengths (1/0)?> ");
            bool discardSingle = int.Parse(Console.ReadLine()) != 0;

            Repetition[]          repetitions         = Repetition.GetTextRepetitions(text);
            Dictionary <int, int> keyLengthWeightings = KeyLengthDeduction.GetKeyLengthWeights(repetitions, discardSingle);
            Dictionary <int, int> factoredWeightings  = KeyLengthDeduction.GetFactoredKeyLengthWeights(keyLengthWeightings);

            Console.Write("View how many top lengths?> ");
            int topLengthsCount = int.Parse(Console.ReadLine());

            int requestCount = topLengthsCount < factoredWeightings.Count ? topLengthsCount : factoredWeightings.Count;
            Dictionary <int, int> topLengths = ProgramMath.GetTopDictionaryKeysByValue(factoredWeightings, requestCount);

            Console.WriteLine();
            Console.WriteLine("(English average IOC is about 0.0667)");
            Console.WriteLine("Top Key Lengths:");

            foreach (int length in topLengths.Keys)
            {
                decimal ioc = KeyLengthDeduction.GetAverageIOCOfTextByOffset(text, length);

                Console.WriteLine($"{length} (weighting = {topLengths[length]}) - Average IOC = {ioc}");
            }

            Console.Write("Select chosen key length> ");

            int keyLengthSelection = int.Parse(Console.ReadLine());

            return(keyLengthSelection);
        }
        private static string ConstructCurrentDeciphering(string[] selections,
                                                          int[] selectionShifts)
        {
            string[] currentSelections = new string[selections.Length];
            for (int i = 0; i < currentSelections.Length; i++)
            {
                currentSelections[i] = FrequencyAnalysis.DecipherTextByMapping(selections[i],
                                                                               ProgramMath.GetCharacterMappingByCaesarCipherOffset(selectionShifts[i]));
            }

            return(FrequencyAnalysis.ReconstructTextFromOffsetSelections(currentSelections));
        }
Beispiel #5
0
        static void DebugGetPermutations()
        {
            Console.Write("Values> ");
            string[] values = Console.ReadLine().Split(',');

            foreach (List <string> perm in ProgramMath.GetPermutations(new List <string>(values)))
            {
                foreach (string part in perm)
                {
                    Console.Write(part);
                }

                Console.WriteLine();
            }
        }
Beispiel #6
0
        public static Dictionary <char, char> GetOptimalCharacterMappingNonCaesar(Dictionary <char, double> textCharProportion,
                                                                                  Dictionary <char, double> targetCharProportion,
                                                                                  out double mappingDifference)
        {
            /*Mappings are { inputTextChar : actualChar }*/

            double minDifference = double.MaxValue;
            Dictionary <char, char> optimalMapping = null;

            foreach (List <char> charList in ProgramMath.GetPermutations(new List <char>(Program.validCharacters)))
            {
                /*Create Character Mapping*/

                Dictionary <char, char> mapping = new Dictionary <char, char>();

                for (int i = 0; i < Program.validCharacters.Length; i++)
                {
                    mapping[charList[i]] = Program.validCharacters[i];
                }

                /*Test character mapping*/

                Dictionary <char, double> mappedCharProportions = new Dictionary <char, double>();

                foreach (char key in textCharProportion.Keys)
                {
                    mappedCharProportions[mapping[key]] = textCharProportion[key];
                }

                double difference = ProgramMath.GetKeyFrequencyDifference(mappedCharProportions, targetCharProportion);

                /*Compare mapping to best*/

                if (difference < minDifference)
                {
                    minDifference  = difference;
                    optimalMapping = new Dictionary <char, char>(mapping);
                }
            }


            mappingDifference = minDifference;
            return(optimalMapping);
        }
Beispiel #7
0
        public static Dictionary <char, char> GetOptimalCharacterMapping(Dictionary <char, double> textCharProportion,
                                                                         Dictionary <char, double> targetCharProportion,
                                                                         out double mappingDifference,
                                                                         out int mappingShiftAmount)
        {
            /*Mappings are { inputTextChar : actualChar }*/

            double minDifference = double.MaxValue;
            Dictionary <char, char> optimalMapping = null;
            int optimalShiftAmount = 0;

            for (int i = 0; i < 26; i++)
            {
                /*Create Character Mapping*/

                Dictionary <char, char> mapping = ProgramMath.GetCharacterMappingByCaesarCipherOffset((26 - i) % 26);

                /*Test character mapping*/

                Dictionary <char, double> mappedCharProportions = new Dictionary <char, double>();

                foreach (char key in textCharProportion.Keys)
                {
                    mappedCharProportions[mapping[key]] = textCharProportion[key];
                }

                double difference = ProgramMath.GetKeyFrequencyDifference(mappedCharProportions, targetCharProportion);

                /*Compare mapping to best*/

                if (difference < minDifference)
                {
                    minDifference      = difference;
                    optimalMapping     = new Dictionary <char, char>(mapping);
                    optimalShiftAmount = i;
                }
            }


            mappingDifference  = minDifference;
            mappingShiftAmount = optimalShiftAmount;
            return(optimalMapping);
        }
Beispiel #8
0
        static void DebugBinaryPossibilities()
        {
            Console.Write("Length> ");
            int length = int.Parse(Console.ReadLine());

            List <List <bool> > possibilities = ProgramMath.GetBinaryPossibilities(length);

            Console.WriteLine($"{possibilities.Count} found");

            foreach (List <bool> possibility in possibilities)
            {
                foreach (bool value in possibility)
                {
                    Console.Write(value ? "1" : "0");
                }

                Console.WriteLine();
            }
        }
        public static Dictionary <int, int> GetFactoredKeyLengthWeights(Dictionary <int, int> originalKeyLengthWeightings)
        {
            Dictionary <int, int> outputWeightings = new Dictionary <int, int>();

            foreach (int keyLength in originalKeyLengthWeightings.Keys)
            {
                int[] lengthFactors = ProgramMath.GetFactors(keyLength);

                foreach (int factor in lengthFactors)
                {
                    if (outputWeightings.ContainsKey(factor))
                    {
                        outputWeightings[factor] += originalKeyLengthWeightings[keyLength];
                    }
                    else
                    {
                        outputWeightings.Add(factor, originalKeyLengthWeightings[keyLength]);
                    }
                }
            }

            return(outputWeightings);
        }
        /// <summary>
        /// Get the likelihood of possible key lengths given repetitions that have been found in a text
        /// </summary>
        /// <param name="repetitions">The repetitions that have been found in a text</param>
        /// <returns>{keyLength : occurences}</returns>
        public static Dictionary <int, int> GetKeyLengthWeights(Repetition[] repetitions,
                                                                bool discardSingleOccurence = false)
        {
            Dictionary <int, int> lengthWeightings = new Dictionary <int, int>();

            foreach (Repetition repetition in repetitions)
            {
                List <List <int> > positionsActivePossibilities = ProgramMath.GetListActivePossibilities(repetition.positions, true);

                foreach (List <int> positions in positionsActivePossibilities)
                {
                    //Try each combination of repetitions being checked and not being checked in case some where coincidence

                    bool valid = true; /*All spacings are equal*/

                    int spacing = positions[1] - positions[0];

                    if (positions.Count > 2)
                    {
                        for (int i = 2; i < positions.Count; i++)
                        {
                            if (positions[i] - positions[i - 1] != spacing)
                            {
                                valid = false;
                            }
                        }
                    }

                    if (valid)
                    {
                        if (lengthWeightings.ContainsKey(spacing))
                        {
                            lengthWeightings[spacing]++;
                        }
                        else
                        {
                            lengthWeightings.Add(spacing, 1);
                        }
                    }
                }
            }

            if (discardSingleOccurence)
            {
                Dictionary <int, int> newOutput = new Dictionary <int, int>();

                foreach (int key in lengthWeightings.Keys)
                {
                    if (lengthWeightings[key] > 1)
                    {
                        newOutput.Add(key, lengthWeightings[key]);
                    }
                }

                return(newOutput);
            }
            else
            {
                return(lengthWeightings);
            }
        }
        public static string RunDeciphering(string originalText,
                                            int keyLength,
                                            out string keyword)
        {
            //TODO: allow for keyLength bigger than seperateKeyColors.Length
            Debug.Assert(keyLength < seperateKeyColors.Length);

            string[] originalSelections = FrequencyAnalysis.SplitTextByOffset(originalText, keyLength);

            int[] selectionShifts = new int[originalSelections.Length];
            for (int i = 0; i < originalSelections.Length; i++)
            {
                selectionShifts[i] = 0;
            }

            #region Instructions

            PrintSeperator();

            Console.WriteLine("To shift a selection with id i by n (n can be negative), use \"{i}:{n}\"");
            Console.WriteLine("To set the current mapping to a calculated optimal mapping, use SET OPTIMAL");
            Console.WriteLine("To print the text in one color, use PRINT PLAIN");

            PrintSeperator();

            for (int i = 0; i < keyLength; i++)
            {
                Console.ForegroundColor = seperateKeyColors[i];
                Console.Write(i + " ");
            }
            Console.ForegroundColor = defaultConsoleColor;
            Console.WriteLine();

            PrintSeperator();

            #endregion

            bool running = true;
            while (running)
            {
                Console.WriteLine("Current Keyword: " + ProgramMath.GetKeywordFromOffsets(selectionShifts));

                Console.WriteLine("Current Text:");
                PrintColoredTextByKey(ConstructCurrentDeciphering(originalSelections, selectionShifts),
                                      keyLength);

                Console.Write("> ");
                string inputRequest = Console.ReadLine().ToUpper();

                if (inputRequest == "" || inputRequest == "END")
                {
                    running = false;
                }
                else if (Regex.IsMatch(inputRequest, @"^\d+:-?\d+$", RegexOptions.IgnoreCase))
                {
                    string[] parts = inputRequest.Split(':');
                    Debug.Assert(parts.Length == 2);

                    int selectionId = int.Parse(parts[0]);
                    int shiftAmount = int.Parse(parts[1]);

                    if (selectionId < 0 ||
                        selectionId >= originalSelections.Length)
                    {
                        Console.WriteLine("Invalid selection id");
                    }
                    else
                    {
                        selectionShifts[selectionId] = (selectionShifts[selectionId] + shiftAmount + Program.validCharacters.Length) % Program.validCharacters.Length;
                    }
                }
                else if (inputRequest == "SET OPTIMAL" || inputRequest == "SETOPTIMAL")
                {
                    for (int selectionIndex = 0; selectionIndex < originalSelections.Length; selectionIndex++)
                    {
                        string selection = originalSelections[selectionIndex];

                        Dictionary <char, double> selectionProportions = FrequencyAnalysis.CharFrequencyToCharProportion(FrequencyAnalysis.GetTextCharFrequency(selection));

                        double _;
                        int    optimalShiftAmount;
                        FrequencyAnalysis.GetOptimalCharacterMapping(selectionProportions,
                                                                     EnglishLetterFrequency.GetLetterProportions(),
                                                                     out _,
                                                                     out optimalShiftAmount);

                        selectionShifts[selectionIndex] = optimalShiftAmount;
                    }
                }
                else if (inputRequest == "PRINT PLAIN" || inputRequest == "PRINTPLAIN")
                {
                    Console.WriteLine(ConstructCurrentDeciphering(originalSelections, selectionShifts));
                }
                else
                {
                    Console.WriteLine("Unknown Request");
                }
            }

            keyword = ProgramMath.GetKeywordFromOffsets(selectionShifts);
            return(ConstructCurrentDeciphering(originalSelections, selectionShifts));
        }
Beispiel #12
0
        static void ReleaseMain(string[] args)
        {
            Console.Write("Text> ");
            string text;

            string input = Console.ReadLine().ToUpper().Replace(" ", "").ToUpper();

            if (input[0] == '\\')
            {
                text = GetTextFromFile(input.Substring(1)).ToUpper();
            }
            else
            {
                text = input;
            }

            foreach (char c in text)
            {
                if (!validCharacters.Contains(c))
                {
                    Console.WriteLine($"Error: Invalid character in text ({c})");
                    return;
                }
            }

            int keyLengthSelection = KeyLengthSelection(text);

            Console.Write("Automatically decipher text (0/1)?> ");
            bool autoDecipher = int.Parse(Console.ReadLine()) != 0;

            if (autoDecipher)
            {
                string[] offsetTextSelections = FrequencyAnalysis.SplitTextByOffset(text, keyLengthSelection);

                string[] decipheredStrings = new string[offsetTextSelections.Length];
                int[]    shiftAmounts      = new int[offsetTextSelections.Length];

                for (int i = 0; i < decipheredStrings.Length; i++)
                {
                    string selection = offsetTextSelections[i];

                    double _;
                    Dictionary <char, double> selectionProportions = FrequencyAnalysis.CharFrequencyToCharProportion(FrequencyAnalysis.GetTextCharFrequency(selection));
                    Dictionary <char, char>   optimalMapping       = FrequencyAnalysis.GetOptimalCharacterMapping(selectionProportions,
                                                                                                                  EnglishLetterFrequency.GetLetterProportions(),
                                                                                                                  out _,
                                                                                                                  out shiftAmounts[i]);

                    decipheredStrings[i] = FrequencyAnalysis.DecipherTextByMapping(selection, optimalMapping);
                }

                string fullDeciphering = FrequencyAnalysis.ReconstructTextFromOffsetSelections(decipheredStrings);

                Console.WriteLine("Keyword: " + ProgramMath.GetKeywordFromOffsets(shiftAmounts));
                Console.WriteLine("Deciphered Text:");
                Console.WriteLine(fullDeciphering);
            }
            else
            {
                string keyword;
                string fullDeciphering = ManualMappingDeciphering.RunDeciphering(text,
                                                                                 keyLengthSelection,
                                                                                 out keyword);

                Console.WriteLine("Keyword: " + keyword);
                Console.WriteLine("Deciphered Text:");
                Console.WriteLine(fullDeciphering);
            }
        }
Beispiel #13
0
        static void DebugOptimalCharacterMappingFull()
        {
            Console.Write("Text> ");
            string text = Console.ReadLine().ToUpper();

            const bool discardSingle = true;

            Repetition[]          repetitions         = Repetition.GetTextRepetitions(text);
            Dictionary <int, int> keyLengthWeightings = KeyLengthDeduction.GetKeyLengthWeights(repetitions, discardSingle);
            Dictionary <int, int> factoredWeightings  = KeyLengthDeduction.GetFactoredKeyLengthWeights(keyLengthWeightings);

            const int topLengthsCount = 7;

            Dictionary <int, int> topLengths = ProgramMath.GetTopDictionaryKeysByValue(factoredWeightings, topLengthsCount);

            Console.WriteLine();
            Console.WriteLine("Top Key Lengths:");

            foreach (int length in topLengths.Keys)
            {
                Console.WriteLine($"{length} (weighting = {topLengths[length]})");
            }

            Console.Write("Select chosen key length> ");

            int keyLengthSelection = int.Parse(Console.ReadLine());

            string[] selections = FrequencyAnalysis.SplitTextByOffset(text, keyLengthSelection);

            Console.WriteLine();
            Console.WriteLine("Text Offset Selections:");

            for (int i = 0; i < selections.Length; i++)
            {
                Console.WriteLine(i + ") " + selections[i]);
            }

            Console.Write("Select text offset selection> ");
            int offsetSelectionIndex = int.Parse(Console.ReadLine());

            Debug.Assert(0 <= offsetSelectionIndex &&
                         offsetSelectionIndex < selections.Length);

            string selectedTextOffsetSelection = selections[offsetSelectionIndex];

            Dictionary <char, double> selectionCharacterProportion = FrequencyAnalysis.CharFrequencyToCharProportion(FrequencyAnalysis.GetTextCharFrequency(selectedTextOffsetSelection));

            Dictionary <char, double> englishCharacterProportions = EnglishLetterFrequency.GetLetterProportions();

            double mappingDifference;
            int    _;
            Dictionary <char, char> optimalMapping = FrequencyAnalysis.GetOptimalCharacterMapping(selectionCharacterProportion,
                                                                                                  englishCharacterProportions,
                                                                                                  out mappingDifference,
                                                                                                  out _);

            Console.WriteLine();
            Console.WriteLine($"Mapping Difference: {mappingDifference}");

            foreach (char textChar in optimalMapping.Keys)
            {
                Console.WriteLine($"{textChar} -> {optimalMapping[textChar]}");
            }
        }