コード例 #1
0
        /// <summary>Decrypt a Book Cipher using a string representation of integer cipher numbers and a set of key words.</summary>
        /// <param name="cipherNums">an ordered list of 1-based cipher numbers (word indexes) in string format</param>
        /// <param name="keyWords">an ordered list of key words used to encrypt the document.</param>
        /// <param name="letterSel">a choice of first letter or last letter from key word to encrypt document</param>
        /// <param name="throwOnOutOfRange">a flag to raise an exception if a number exceeds the range of key text. If false, a question-mark will be returned.</param>
        /// <returns>a string representation of decrypted text without any punctuation or spacing</returns>
        /// <remarks>A zero or negative number will still raise an exception regardless of the throwOnOutOfRange value.</remarks>
        public static string Decrypt(IEnumerable <string> cipherNums, IEnumerable <string> keyWords, LetterSelection letterSel = LetterSelection.FirstLetter, OutOfBoundsIndex outOfRangeHandler = OutOfBoundsIndex.ThrowException)
        {
            int num      = 0;
            var numArray = cipherNums.ToArray();

            int[] nums = new int[numArray.Length];
            // validation of cipher numbers being valid string representations of integers
            for (int ndx = 0; ndx < numArray.Length; ndx++)
            {
                var trimmedNum = numArray[ndx].Trim();
                if (int.TryParse(trimmedNum, out num) == false)
                {
                    throw new FormatException($"Cipher number {ndx + 1} has an invalid number ({trimmedNum}).");
                }
                nums[ndx] = num;
            }
            return(Decrypt(nums, keyWords, letterSel, outOfRangeHandler));
        }
コード例 #2
0
 /// <summary>Decrypt a Book Cipher using a list of integer cipher numbers and a set of key words.</summary>
 /// <param name="cipherNums">an ordered list of 1-based cipher numbers (word indexes)</param>
 /// <param name="keyWords">an ordered list of key words used to encrypt the document.</param>
 /// <param name="letterSel">a choice of first letter or last letter from key word to encrypt document</param>
 /// <param name="throwOnOutOfRange">a flag to raise an exception if a number exceeds the range of key text. If false, a question-mark will be returned.</param>
 /// <returns>a string representation of decrypted text without any punctuation or spacing</returns>
 /// <remarks>A zero or negative number will still raise an exception regardless of the throwOnOutOfRange value.</remarks>
 public static string Decrypt(IEnumerable <int> cipherNums, IEnumerable <string> keyWords, LetterSelection letterSel = LetterSelection.FirstLetter, OutOfBoundsIndex outOfRangeHandler = OutOfBoundsIndex.ThrowException)
 {
     string[] wdArray  = keyWords.ToArray();
     char[]   charList = new char[wdArray.Length];
     for (int ndx = 0; ndx < wdArray.Length; ndx++)
     {
         if (wdArray[ndx] == null)
         {
             throw new ArgumentException($"Word {ndx + 1} is null.");
         }
         wdArray[ndx] = wdArray[ndx].Trim();
         if (wdArray[ndx] == string.Empty)
         {
             throw new ArgumentException($"Word {ndx + 1} is empty.");
         }
         int letterNdx = (letterSel == LetterSelection.FirstLetter) ? 0 : wdArray[ndx].Length - 1;
         charList[ndx] = (wdArray[ndx])[letterNdx];
     }
     return(Decrypt(cipherNums, charList, outOfRangeHandler));
 }
コード例 #3
0
        /// <summary>Encrypt text using a set of key words from a book or document</summary>
        /// <param name="plainTextWords">an ordered list of text to encrypt</param>
        /// <param name="bookText">an ordered list of words used to encrypt; repeats are okay and recommended.</param>
        /// <param name="delimiter">the delimeter to use for separating numbers; typical is comma or space</param>
        /// <param name="letterSel">a choice of first letter or last letter of key word to encrypt document</param>
        /// <returns>a string of encrypted text</returns>
        public static string Encrypt(string plainText, IEnumerable <string> bookText, char delimiter, LetterSelection letterSel = LetterSelection.FirstLetter)
        {
            Random rnd    = new Random();
            var    lookup = new Dictionary <char, List <int> >();
            int    cnt    = 0;

            foreach (var wd in bookText)
            {
                if (string.IsNullOrEmpty(wd))
                {
                    throw new ArgumentException($"Word {cnt + 1} is null or empty.");
                }
                var oneWord = wd.Trim().ToLower();
                if (oneWord == string.Empty)
                {
                    throw new ArgumentException($"Word {cnt + 1} is whitespace.");
                }
                int  letterNdx = (letterSel == LetterSelection.FirstLetter) ? 0 : oneWord.Length - 1;
                char c         = oneWord[letterNdx];
                if (lookup.ContainsKey(c))
                {
                    lookup[c].Add(cnt + 1); // add to list
                }
                else
                {
                    var intList = new List <int> {
                        cnt + 1
                    };
                    lookup.Add(c, intList);
                }
                cnt++;
            }
            // now each letter has an associated list of word indexes (which can be chosen at random) to encrypt each letter of the plaintext
            var  sb       = new StringBuilder();
            bool firstNum = true;

            for (int ndx = 0; ndx < plainText.Length; ndx++)
            {
                char c = (plainText.Substring(ndx, 1).ToLower())[0];
                if (char.IsLetter(c))
                {
                    if (lookup.ContainsKey(c) == false)
                    {
                        throw new ArgumentOutOfRangeException($"letter {c} is not found in any words of book text.");
                    }
                    var intList    = lookup[c];
                    var numChoices = intList.Count;
                    // todo: replace Random with crypto-quality PNG
                    int wdChoiceNdx = (numChoices == 1) ? 0 : rnd.Next(intList.Count);
                    if (firstNum == false)
                    {
                        sb.Append($"{delimiter}");
                    }
                    sb.Append($"{intList[wdChoiceNdx]}");
                    firstNum = false;
                }
            }
            return(sb.ToString());
        }