public bool IsValidCipherKey(PlayfairKey cipherKey)
        {
            if (cipherKey == null ||
                string.IsNullOrWhiteSpace(cipherKey.Value) ||
                cipherKey.Value.Equals(Alphabet) ||
                cipherKey.Value.Contains(OmittedCharacter) ||
                cipherKey.Value.Length != Alphabet.Length ||
                !cipherKey.Value.Equals(PlayfairUtil.GetSanitisedString(cipherKey.Value)) ||
                cipherKey.Value.Any(c => !char.IsLetter(c) || !char.IsUpper(c)))
            {
                return(false);
            }

            // Once every other condition is met, need to ensure all characters are unique.
            var observedCharacters = new HashSet <char>();

            foreach (var character in cipherKey.Value)
            {
                if (observedCharacters.Contains(character))
                {
                    return(false);
                }

                observedCharacters.Add(character);
            }

            return(true);
        }
        public PlayfairKey GenerateCipherKey(string memorableKey)
        {
            // Filter out all the unnecessary/redundant/unsupported characters.
            var sanitisedKey = GetSanitisedKey(PlayfairUtil.GetSanitisedString(memorableKey));

            return(new PlayfairKey
            {
                // If necessary amount of characters is present then key is done, alternatively fill in missing values.
                Value = sanitisedKey.Length == Alphabet.Length
                    ? sanitisedKey
                    : GetCompleteCipherKey(sanitisedKey)
            });
        }
예제 #3
0
        public IEnumerable <Digraph> GetCipherTextDigraphs(string cipherText)
        {
            if (!PlayfairUtil.IsValidCipherText(cipherText))
            {
                throw new ArgumentException("Invalid cipher text.");
            }

            var digrapths = new List <Digraph>();

            for (var i = 0; i < cipherText.Length; i += PlayfairUtil.DigrathDenominator)
            {
                digrapths.Add(new Digraph(cipherText[i], cipherText[i + 1]));
            }

            Digraths = digrapths;
            return(digrapths);
        }
예제 #4
0
        public string ReplaceMostCommonDigraphs(string cipherText, IEnumerable <Digraph> replacementDigraphs)
        {
            if (!PlayfairUtil.IsValidCipherText(cipherText))
            {
                throw new ArgumentOutOfRangeException(nameof(cipherText));
            }
            replacementDigraphs = replacementDigraphs as Digraph[] ?? replacementDigraphs.ToArray();
            if (replacementDigraphs == null || !replacementDigraphs.Any())
            {
                throw new ArgumentOutOfRangeException(nameof(replacementDigraphs));
            }

            // Get all digraths and count their occurance count
            var analysedDigraphs = new Dictionary <string, AnalysedDigrath>();

            var cipherTextDigraphs = _digraphGenerator.GetCipherTextDigraphs(cipherText);

            foreach (var digraph in cipherTextDigraphs)
            {
                if (analysedDigraphs.ContainsKey(digraph.ToString()))
                {
                    // Update the occurance count if digraph has already been observed.
                    analysedDigraphs[digraph.ToString()].OccurenceCount++;
                }
                else
                {
                    // Add new digraph to the dictionary and count the initial occurance.
                    analysedDigraphs.Add(digraph.ToString(), new AnalysedDigrath
                    {
                        Digraph        = digraph,
                        OccurenceCount = 1
                    });
                }
            }

            // Commentted out as this metric isn't currently needed. Left within the function for easy future
            // implementation.

            /* Calculate digram frequency & order digrams by their occurance.
             * var cipherTextDigramCount = cipherText.Length / DigramDenominator;
             * foreach (var analysedDigram in analysedDigrams)
             * {
             *  analysedDigram.Value.CalculateFrequency(cipherTextDigramCount);
             * }
             */

            // Orders digraphs by descending order of occurance count and extracts amount to match method input.
            var orderedAnalysedDigraphs = analysedDigraphs
                                          .OrderByDescending(kv => kv.Value.OccurenceCount)
                                          .Take(replacementDigraphs.Count())
                                          .ToArray();

            // Create a replacement map for the most common digraphs.
            var digraphReplacementMap = new Dictionary <string, Digraph>();

            for (var i = 0; i < replacementDigraphs.Count(); i++)
            {
                digraphReplacementMap.Add(orderedAnalysedDigraphs[i].Key, replacementDigraphs.ElementAt(i));
            }

            // Reconstruct the cipher text whilst replacing the most common digraphs within original cipher text with
            // most frequent digraphs in the assumed language.
            var sb = new StringBuilder(string.Empty);

            foreach (var digraph in cipherTextDigraphs)
            {
                sb.Append(digraphReplacementMap.ContainsKey(digraph.ToString())
                    ? digraphReplacementMap[digraph.ToString()]
                    : digraph);
            }
            return(sb.ToString());
        }
예제 #5
0
 public void IsCipherTextValid_InvalidCipherText_IsFalse(string cipherText)
 {
     Assert.IsFalse(PlayfairUtil.IsValidCipherText(cipherText));
 }