From ac4a8cb406377081eb1c1de2a3abe482508d6f57 Mon Sep 17 00:00:00 2001 From: DarkFeather Date: Tue, 5 Dec 2017 17:13:49 -0600 Subject: [PATCH] Fixes from usability testing --- Affine.csharp | 3 +-- Analysis.csharp | 20 +++++++++++++++++--- Caesarian.csharp | 4 ++-- Cipher.csharp | 12 ++++++++++-- CryptoWorkbench.csharp | 29 ++++++++++++++++++----------- PKGBUILD | 2 +- Simple.csharp | 3 ++- Substitution.csharp | 5 +++-- 8 files changed, 54 insertions(+), 24 deletions(-) diff --git a/Affine.csharp b/Affine.csharp index 63d88b0..a1d44cb 100644 --- a/Affine.csharp +++ b/Affine.csharp @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace AniNIX.Crypto { public class Affine : Cipher { - public override String Description() { return "The Affine cipher\nKey format is two numbers, where the second number is coprime to the first."; } + public override String Description() { return "The Affine cipher\nKey format is two numbers, where the second number is coprime to the first.\n\nExample: affine encrypt 5 3\n\n"; } public override String Command() {return "affine";} public Affine(Workbench w) : base (w) {} @@ -62,7 +62,6 @@ namespace AniNIX.Crypto { for (int x=1; x < 27; x++) { //Try to find a number where the input times that number mod 26 is 1. If we roll through 26 numbers and don't find it, there isn't one. if ((a*x)%26 == 1) { - Console.WriteLine(String.Format("Found Multiplicative Inverse of {0}",x)); return x; } } diff --git a/Analysis.csharp b/Analysis.csharp index abb3583..ec3c2fa 100644 --- a/Analysis.csharp +++ b/Analysis.csharp @@ -9,7 +9,7 @@ namespace AniNIX.Crypto { public class Analysis : Cipher { private Substitution _sb; - public override String Description() { return "Analysis tools"; } + public override String Description() { return "These are analysis tools to help understand ciphers."; } public override String Command() { return "analysis"; } public Analysis(Workbench w) : base (w) { @@ -45,9 +45,16 @@ namespace AniNIX.Crypto { case "charinfo": CharInfo(line); break; - default: + case "hexprint": + HexPrint(workSpace); + break; + case "help": + case "": GetHelp(); break; + default: + Console.Error.WriteLine("Invalid command. Type 'analysis help' for more."); + break; } return workSpace; } @@ -56,7 +63,7 @@ namespace AniNIX.Crypto { /// Show this help text /// public override void GetHelp() { - Console.WriteLine("Analysis tools help:\nfreq -- Get frequency of characters.\nfreqinfo -- Return the most common English frequencies.\none-to-one -- See if there is a direct correspondence of characters between cipher and workspace.\ndiff a b -- get the difference between two characters\ncharinfo -- get the info about a character"); + Console.WriteLine("Analysis tools help:\nanalysis freq -- Get frequency of characters.\nanalysis freqinfo -- Return the most common English frequencies.\nanalysis one-to-one -- See if there is a direct correspondence of characters between cipher and workspace.\nanalysis diff a b -- get the difference between two characters\nanalysis charinfo c -- get the info about a character c.\nanalysis hexprint -- print the hex and decimal value of each character in the workspace."); } /// @@ -343,6 +350,13 @@ namespace AniNIX.Crypto { Console.WriteLine(String.Format("Alphabet index: {0}",(Char.IsUpper(line[2][0])) ? (int)line[2][0] - (int)'A' : (int)line[2][0] - (int)'a')); } } + + public void HexPrint(String line) { + Console.WriteLine("Char - Dec - Hex"); + foreach (char i in line.ToCharArray()) { + Console.WriteLine("{0} -- {1} -- {2}",i,(int)i,Convert.ToByte(i)); + } + } //Analysis doesn't handle encryption or decryption, but we want to use the same code for subscribing. public override String Encrypt(string workSpace,String ciphetText,String[] line) { return workSpace; } diff --git a/Caesarian.csharp b/Caesarian.csharp index c15a55f..ef7c0e9 100644 --- a/Caesarian.csharp +++ b/Caesarian.csharp @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace AniNIX.Crypto { public class Caesarian : Cipher { - public override String Description() { return "Caesarian cipher suite\nKey format is a numeric shift."; } + public override String Description() { return "Caesarian ciphers shift letters by a numeric offset. Key format is thus a number."; } public override String Command() { return "caesar"; } public Caesarian(Workbench w) : base (w) {} @@ -42,7 +42,7 @@ namespace AniNIX.Crypto { /// public override void GetHelp() { Console.WriteLine(String.Format("Help for the {0} cipher suite.\n{1}\n",Command(),Description())); - Console.WriteLine("encrypt key -- encrypt with the key\ndecrypt key -- decrypt with the key\nbrute -- brute-force for keys\nhelp -- show this helptext."); + Console.WriteLine("caesar encrypt key -- encrypt with the key\ncaesar decrypt key -- decrypt with the key\ncaesar brute -- brute-force for keys\ncaesar help -- show this helptext."); } diff --git a/Cipher.csharp b/Cipher.csharp index 4501a64..5f2f04d 100644 --- a/Cipher.csharp +++ b/Cipher.csharp @@ -45,6 +45,7 @@ namespace AniNIX.Crypto { case "decrypt": return Decrypt(workSpace,inputText,line); case "help": + case "": GetHelp(); return workSpace; default: @@ -58,8 +59,15 @@ namespace AniNIX.Crypto { /// /// This is the incoming line and we use it to get the cipher name public virtual void GetHelp() { - Console.WriteLine(String.Format("Help for the {0} cipher suite.\n{1}\n",Command(),Description())); - Console.WriteLine("encrypt key -- encrypt with the key\ndecrypt key -- decrypt with the key\nhelp -- show this helptext."); + String command = Command(); + Console.WriteLine(String.Format("Help for the {0} cipher suite.\n{1}\n",command,Description())); + Console.WriteLine("Usage:"); + Console.Write(command); + Console.WriteLine(" encrypt key -- encrypt with the key"); + Console.Write(command); + Console.WriteLine(" decrypt key -- decrypt with the key"); + Console.Write(command); + Console.WriteLine(" help -- show this helptext."); } /// diff --git a/CryptoWorkbench.csharp b/CryptoWorkbench.csharp index 2b17887..b2ee84d 100644 --- a/CryptoWorkbench.csharp +++ b/CryptoWorkbench.csharp @@ -24,7 +24,7 @@ namespace AniNIX.Crypto { private void ReadCipher(String[] line) { // If a filename's not provided. if (line == null || line.Length !=2) { - Console.WriteLine("Please paste your ciphertext."); + Console.WriteLine("Please paste your ciphertext. End your input with a trailing newline."); string readLn = Console.ReadLine(); StringBuilder sb = new StringBuilder(); //Read lines from stdin until a blank line is given. @@ -74,38 +74,40 @@ namespace AniNIX.Crypto { this._isBlind = true; ReadCipher(null); // Otherwise, try to use the first argument as a filename. + } else if (args[0].Equals("--help") || args[0].Equals("-h")) { } else { String[] line = new String[2]; line[0] = "reread"; line[1] = args[0]; ReadCipher(line); - } + } // Otherwise, give some help and exit. } else { Console.Error.WriteLine("The only argument allowed is a filename containing the ciphertext or --blind to block filesystem access."); System.Environment.Exit(1); } // Seed the helptext. - HelpText.Append("You can get help on any command by running \" help\".\nSuppress printing the cipher with a trailing ;.\nAvailable commands:\n"); + HelpText.Append("Available commands:\n"); // Don't tell users about things they can't use. if (!_isBlind) { HelpText.Append("reread -- Read in a new cipher\n"); HelpText.Append("write -- write the workspace to a file\n"); } - HelpText.Append("regex -- Check for strings with the two regex arguments: [search] [filter]\n"); HelpText.Append("reset -- reset workspace to the ciphertext.\n"); + HelpText.Append("regex -- Check for strings with the two regex arguments: [search] [filter]\n"); HelpText.Append("links -- show some helpful links\n"); - HelpText.Append("help -- show this HelpText\n"); HelpText.Append("print -- show the current workspace\n"); HelpText.Append("display -- alias of print\n"); - HelpText.Append("exit -- exit and show the result.\n"); - HelpText.Append("quit -- alias of exit.\n"); // Initialize the ciphersuites. Object[] cipherArgs = { (Object)this }; foreach (Type cipherType in Assembly.GetAssembly(typeof(Cipher)).GetTypes() .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(Cipher)))) { _ciphers.Add((Cipher)Activator.CreateInstance(cipherType, cipherArgs)); } + HelpText.Append("exit -- exit and show the result.\n"); + HelpText.Append("quit -- alias of exit.\n"); + HelpText.Append("help -- show this HelpText\n"); + HelpText.Append("\nYou can get help on any command by running \" help\".\nSuppress printing the cipher with a trailing ;.\n\nCommand structure is: {module} {operation} [{keypart}]*\n\nExample commands:\n\"caesar encrypt 13\" -- Encrypt the input with a Caesarian cipher of offset 13.\n\"affine help\" -- Get help on the Affine cipher.\n\"simple stripspace\" -- Use the Simple module to remove spaces.\n\"analysis one-to-one\" -- Check if the workspace is a one-to-one correlation with the input.\n\n"); } /// @@ -124,7 +126,9 @@ namespace AniNIX.Crypto { /// /// Display this workbench to stdout with colors. /// - public void Print() { + // Set to true if you want verbose prints. + public void Print() { Print(false); } + public void Print(bool verbose) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Input:"); Console.ResetColor(); @@ -132,6 +136,7 @@ namespace AniNIX.Crypto { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Workspace:"); Console.ResetColor(); + if (verbose) return; List topletters = Analysis.GetMostCommonLetters(workSpace).Take(5).ToList();//cyan List bigrams = Analysis.Top(Analysis.GetSubstrings(workSpace,2)); //yellow List trigrams = Analysis.Top(Analysis.GetSubstrings(workSpace,3));//magenta @@ -199,10 +204,12 @@ namespace AniNIX.Crypto { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("### Welcome to the AniNIX::CryptoWorkbench ###"); Console.ResetColor(); + Console.WriteLine("Type help for assistance.\n"); + Print(); try { // Set the initial command to be show the helptext. - string command = "help"; - string read = "help"; + string command = ""; + string read = ""; string[] line; bool showCipher=true; @@ -275,7 +282,7 @@ namespace AniNIX.Crypto { // Show the cipher if the user asked. if (showCipher) Print(); // Display an AniNIX-standard prompt. - Console.Write("\nWhat command would you like to execute?\n"); + Console.Write("\nCW "); Console.ForegroundColor = ConsoleColor.Red; Console.Write("|"); Console.ResetColor(); diff --git a/PKGBUILD b/PKGBUILD index c00654f..5aa15a6 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,6 +1,6 @@ # Maintainer: Shikoba Kage pkgname=cryptoworkbench -pkgver=0.1 +pkgver=0.1-1 pkgrel=1 epoch= pkgdesc="AniNIX::CryptoWorkbench \\\\ Simple Cryptography Utility" diff --git a/Simple.csharp b/Simple.csharp index d06b270..71db1b7 100644 --- a/Simple.csharp +++ b/Simple.csharp @@ -33,6 +33,7 @@ namespace AniNIX.Crypto { case "reverse": return ReverseString(workSpace); case "help": + case "": GetHelp(); return workSpace; default: @@ -47,7 +48,7 @@ namespace AniNIX.Crypto { /// This is the incoming line and we use it to get the cipher name public override void GetHelp() { Console.WriteLine(String.Format("Help for the {0} cipher suite.\n{1}\n",Command(),Description())); - Console.WriteLine("shiftup -- Make all uppercase\nshiftdown -- Make all lowercase\nstripspace -- strip spaces from String\nreverse -- reverse the string\nhelp -- show this helptext."); + Console.WriteLine("Usage:\nsimple shiftup -- Make all uppercase\nsimple shiftdown -- Make all lowercase\nsimple stripspace -- strip spaces from String\nsimple reverse -- reverse the string\nsimple help -- show this helptext."); } diff --git a/Substitution.csharp b/Substitution.csharp index b75172e..b540df3 100644 --- a/Substitution.csharp +++ b/Substitution.csharp @@ -8,7 +8,7 @@ namespace AniNIX.Crypto { public char[] EngCommon = {'e','t','a','o','i','n','s','h','r','d','l','u','c','m','w','f','y','g','p','b','v','k','x','j','q','z'}; - public override String Description() { return "Subsitution cipher suite\nKey format is \"E[EEE]=d[ddd]\", where E is the character in the cipher and d is the intended character in the workspace."; } + public override String Description() { return "Substitution ciphers replace characters one-for-one.\nKey format is \"E[EEE]=d[ddd]\", where E is the character in the cipher and d is the intended character in the workspace.\n\nSubstitution can take multiple keys in a single invocation.\n\nExample usage:\nsub decrypt I=j -- replace each I in the input with j in the workspace.\nsub decrypt IN=jq -- replace each I in the input with j in the workspace, and each N in the input with q.\nsub decrypt IN=jq K=c -- do the above, and additionally replace each K with c.\n"; } public override String Command() { return "sub"; } public Substitution(Workbench w) : base (w) {} @@ -32,6 +32,7 @@ namespace AniNIX.Crypto { case "try-common": return TryCommon(inputText); case "help": + case "": GetHelp(); return workSpace; default: @@ -46,7 +47,7 @@ namespace AniNIX.Crypto { /// This is the incoming line and we use it to get the cipher name public override void GetHelp() { Console.WriteLine(String.Format("Help for the {0} cipher suite.\n{1}\n",Command(),Description())); - Console.WriteLine("encrypt key[s] -- encrypt with the key[s]\ndecrypt key[s] -- decrypt with the key[s]\ntry-common -- try common sub keys\nhelp -- show this helptext."); + Console.WriteLine("Usage:\nsub encrypt key[s] -- encrypt with the key[s]\nsub decrypt key[s] -- decrypt with the key[s]\ntry-common -- try common sub keys\nhelp -- show this helptext."); } ///