public void ReducePotentialValues()
 {
     foreach (Node node in AllNodes)
     {
         var neighbourCombinations = Combinator.Combinations(AllNodes, node.MaxNeighbours.Value);
         foreach (IEnumerable <Node> combination in neighbourCombinations)
         {
             //Possible combinations are the sets that:: do not contain the node itself
             if (!combination.ToList().Contains(node)) //&& (node.Edges.Count == 0 || combination.Any(con => con.IsConnected(node))))
             {
                 node.Values.Add(combination.ToList());
             }
         }
         //Values must contain already created edges (if any)
         foreach (Node child in node.Edges.Select(edge => edge.Child).ToList())
         {
             node.Values = node.Values.FindAll(set => set.Contains(child));
         }
     }
 }
        public void CombinationsTest()
        {
            List <int> lst = new List <int> {
                0, 1, 2, 3
            };
            List <List <int> > expected = new List <List <int> >
            {
                new List <int> {
                    0, 1
                }, new List <int> {
                    0, 2
                }, new List <int> {
                    0, 3
                },
                new List <int> {
                    1, 2
                }, new List <int> {
                    1, 3
                }, new List <int> {
                    2, 3
                }
            };
            var combinations          = Combinator.Combinations(lst, 2);
            List <List <int> > actual = new List <List <int> >();

            foreach (IEnumerable <int> combination in combinations)
            {
                actual.Add(combination.ToList());
            }

            actual.ForEach(pair => Trace.WriteLine(string.Join(", ", pair)));
            for (int i = 0; i < actual.Count; i++)
            {
                CollectionAssert.AreEqual(expected[i], actual[i]);
            }
        }
Exemple #3
0
        /// <summary>
        ///     Performs a Kasiski attack provided a given key length
        /// </summary>
        /// <param name="cipherText"></param>
        /// <param name="keyLength"></param>
        /// <returns></returns>
        public static string AttackWithKeyLength(string cipherText, int keyLength)
        {
            var cipher        = new Vigenere();
            var allFreqScores = new List <Dictionary <char, int> >();

            for (var i = 1; i < keyLength + 1; i++)
            {
                var nthLetters = Kasiski.GetNthSubkeysLetters(i, keyLength, cipherText.ToUpper());

                var frequencyScore = new Dictionary <char, int>();
                foreach (var letter in Constants.Letters)
                {
                    var decryptedText = cipher.Decipher(nthLetters, Char.ToString(letter));

                    var score = Frequency.EnglishFreqMatchScore(decryptedText);
                    frequencyScore.Add(letter, score);
                }

                //Sort the dictionary by factor ocurrences descending
                var sortedCommonFactors = (from entry in frequencyScore orderby entry.Value descending select entry)
                                          .Take(4)
                                          .ToDictionary(pair => pair.Key, pair => pair.Value);

                allFreqScores.Add(sortedCommonFactors);
            }

            //Print our possible keys
            var position     = 1;
            var possibleKeys = new List <char[]>();

            foreach (var freq in allFreqScores)
            {
                _log.InfoFormat("Possible letters for letter {0} of the key: ", position);
                var possibleKeyOutput = new StringBuilder();
                var keyStore          = new char[freq.Keys.Count];
                var keyPosition       = 0;
                foreach (var keyPossible in freq.Keys)
                {
                    possibleKeyOutput.AppendFormat("{0}\t", keyPossible);
                    keyStore[keyPosition] = keyPossible;
                    keyPosition++;
                }
                possibleKeys.Add(keyStore);
                _log.InfoFormat(possibleKeyOutput.ToString());
                position++;
            }

            var keyCombinations = Combinator.Combinations(possibleKeys);

            var keyFound = false;
            var key      = string.Empty;

            //Go through the possible keys with the given freqency and determine if they produce
            //an English sentence.
            Parallel.ForEach(keyCombinations, (possibleKey, loopState) =>
            {
                //Stop processing if we find the possible key
                if (keyFound)
                {
                    loopState.Break();
                }

                _log.DebugFormat("Attempting with key: {0}", possibleKey);

                var decryptAttempt = cipher.Decipher(cipherText, possibleKey.ToString());

                if (!English.IsEnglish(decryptAttempt))
                {
                    return;
                }

                _log.InfoFormat("Found Possible Decryption Key: {0}", possibleKey);
                keyFound = true;
                key      = possibleKey.ToString();
            }
                             );

            return(key);
        }