/// <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)); }
/// <summary>/// <summary>Decrypt a Book Cipher using a list of integer cipher numbers and a list of characters used to encrypt.</summary> /// <param name="cipherNums">an ordered list of 1-based cipher numbers (word indexes)</param> /// <param name="letters">a list of characters used to encrypt the text.</param> /// <param name="outOfRangeHandler">how to react to an out of range index number exceeding 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 <char> letters, OutOfBoundsIndex outOfRangeHandler = OutOfBoundsIndex.ThrowException) { var letterLookup = letters.ToArray(); int cnt = 0; StringBuilder sb = new StringBuilder(); foreach (var num in cipherNums) { if (num <= 0) { throw new ArgumentOutOfRangeException($"Entry {cnt + 1} has a number ({num}) less than or equal to zero."); } if (num > letterLookup.Length) { switch (outOfRangeHandler) { case OutOfBoundsIndex.ThrowException: throw new ArgumentOutOfRangeException($"Entry {cnt + 1} has a number ({num}) exceeding word count in key ({letterLookup.Length})"); case OutOfBoundsIndex.ReturnQMark: sb.Append('?'); break; case OutOfBoundsIndex.WrapUsingModulo: int newIndex = (num % letterLookup.Length); if (newIndex == 0) { newIndex = letterLookup.Length; } sb.Append(letterLookup[newIndex - 1]); break; } } else { sb.Append(letterLookup[num - 1]); } cnt++; } return(sb.ToString()); }
/// <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)); }