Converting from Bazaar

Old Log:
------------------------------------------------------------
revno: 16
committer: cxford <cxford@aninix.net>
branch nick: CryptoWorkbench
timestamp: Sun 2016-07-10 20:22:37 -0500
message:
  Some fixes for regex, captive shells, analysis
------------------------------------------------------------
revno: 15
committer: dev <dev@aninix.net>
branch nick: CryptoWorkbench
timestamp: Thu 2016-07-07 13:54:04 -0500
message:
  Adding captivecrypto.bash shell to go with ForceCommand
------------------------------------------------------------
revno: 14
committer: dev <dev@aninix.net>
branch nick: CryptoWorkbench
timestamp: Thu 2016-07-07 13:38:21 -0500
message:
  Updating
------------------------------------------------------------
revno: 13
committer: cxford <cxford@aninix.net>
branch nick: CryptoWorkbench
timestamp: Tue 2016-07-05 13:20:34 -0500
message:
  Adding inline regex lookup
  Updating ciphers to use standard constructor -- now ciphers can be added from new class, new private in WorkBench, and new instantiation in Workbench constructor
------------------------------------------------------------
revno: 12
committer: dev <dev@aninix.net>
branch nick: CryptoWorkbench
timestamp: Sat 2016-06-18 10:16:40 -0500
message:
  GUI enhancements for colorizing. General updates.
------------------------------------------------------------
revno: 11
committer: dev <dev@aninix.net>
branch nick: CryptoWorkbench
timestamp: Mon 2016-05-09 12:21:57 -0500
message:
  Updated letter frequency in analysis
  Added reverse function in Simple
  Updated bash script with small fixes
  Updated cryptoworkbench Links function with link to frequency analysis
------------------------------------------------------------
revno: 10
committer: dev <dev@aninix.net>
branch nick: CryptoWorkbench
timestamp: Fri 2016-04-15 13:03:41 -0500
message:
  Syncing with new ciphers for Affine, Ubchi, Vignere, and Columnar Transposition. Analytics updated and general fixes included. Paradigm shift for cipher inheritance.
------------------------------------------------------------
revno: 9
committer: cxford <cxford@aninix.net>
branch nick: CryptoWorkbench
timestamp: Wed 2016-02-10 15:36:37 -0600
message:
  Added new class for simple operations, like string to upper/lower and removing spaces.
  Updated with file reading and writing.
  Added brute-force for Caesarian ciphers.
  Updated substition and analysis for better options.
  Improved CLI
------------------------------------------------------------
revno: 8
committer: root <root@aninix.net>
branch nick: CryptoWorkbench
timestamp: Mon 2016-02-01 13:44:20 -0600
message:
  Modified analysis to display doubled letters and notify of which letter is repeated when One-to-one query fails to find a one-to-one relationship
------------------------------------------------------------
revno: 7
committer: root <root@aninix.net>
branch nick: CryptoWorkbench
timestamp: Thu 2016-01-28 10:03:40 -0600
message:
  Lots of minor fixes.
------------------------------------------------------------
revno: 6
committer: root <root@aninix.net>
branch nick: CryptoWorkbench
timestamp: Wed 2016-01-20 09:29:54 -0600
message:
  Makefile had a small typo but it prevented installs. Worth a commit.
------------------------------------------------------------
revno: 5
committer: root <root@aninix.net>
branch nick: CryptoWorkbench
timestamp: Tue 2016-01-19 13:12:12 -0600
message:
  Added one-to-one query to Analysis for checking if a substitution or rotation remains one-to-one and to acquire the key
  Moved bash script to ease tab-completion
------------------------------------------------------------
revno: 4
committer: root <root@aninix.net>
branch nick: CryptoWorkbench
timestamp: Thu 2016-01-14 10:24:02 -0600
message:
  Renamed README to be consistent with other branches in repo.
  Added Caesarian functions
  Added analysis and substitution functions for letter substitution.
------------------------------------------------------------
revno: 3
committer: cxford <cxford@aninix.net>
branch nick: CryptoWorkbench
timestamp: Wed 2016-01-13 16:41:05 -0600
message:
  Added install files
------------------------------------------------------------
revno: 2
committer: cxford <cxford@aninix.net>
branch nick: CryptoWorkbench
timestamp: Wed 2016-01-13 16:30:10 -0600
message:
  Adding Makefile and source files.
------------------------------------------------------------
revno: 1
committer: cxford <cxford@aninix.net>
branch nick: CryptoWorkbench
timestamp: Wed 2016-01-13 10:29:31 -0600
message:
  Initializing project tree and adding Readme.
This commit is contained in:
cxford 2016-08-04 12:10:50 -05:00
commit 65dbd8cae2
21 changed files with 1433 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
CryptoApplet.java

5
ForceCommand.txt Normal file
View File

@ -0,0 +1,5 @@
Match User crypto
ForceCommand /usr/local/bin/captivecrypto
X11Forwarding no
PermitTunnel no
AllowTcpForwarding no

36
Makefile Normal file
View File

@ -0,0 +1,36 @@
TMUXSetting != grep -c "cryptoworkbench" /etc/tmux.conf
compile: clean /usr/bin/mcs analysis.csharp substitution.csharp caesarian.csharp cryptoworkbench.csharp
/usr/bin/mcs -out:cryptoworkbench.exe *.csharp
test: /usr/bin/mono compile
/usr/bin/mono cryptoworkbench.exe ./sample.txt
clean:
if [ -f cryptoworkbench.exe ]; then rm cryptoworkbench.exe; fi
install: compile /bin/bash bash.cryptoworkbench
mv cryptoworkbench.exe /opt
chmod 0555 /opt/cryptoworkbench.exe
cp bash.cryptoworkbench /usr/local/bin/cryptoworkbench
chmod 0555 /usr/local/bin/cryptoworkbench
cp captivecrypto.bash /usr/local/bin/captivecrypto
chown root:root /usr/local/bin/captivecrypto
chmod 0755 /usr/local/bin/captivecrypto
webapp: install
javac CryptoApplet.java
@echo TODO this is a work in progress.
@echo Install the CryptoApplet.class and crypto.phpsnip into a webpage for your site.
sshuser: install ForceCommand.txt
grep captivecrypto /etc/shells || echo '/usr/local/bin/captivecrypto' /etc/shells
id crypto || useradd -k -d /home/crypto -s /usr/local/bin/captivecrypto crypto
cat ./ForceCommand.txt >> /etc/ssh/sshd_config
echo crypto | passwd --stdin crypto
tmux: /usr/bin/tmux
@echo Making sure cryptoworkbench setting isn\'t already in /etc/tmux.conf...
[ "${TMUXSetting}" -eq 0 ]
echo "bind-key -T prefix x new-window cryptoworkbench" >> /etc/tmux.conf
echo 'bind-key -T prefix X confirm-before -p "kill-pane #P? (y/n)" kill-pane' >> /etc/tmux.conf

9
README.bzr Normal file
View File

@ -0,0 +1,9 @@
This project is to allow easy deciphering of text-based ciphers. We will start with basic functions and add new ones as possible.
The format for this project should be as follows:
* cryptoworkbench.csharp contains CLI commands and command reference to each cipher's API.
* Analysis functions should be placed in the Analysis class, and simple character operations go in Simple.
* CharGrid offers a means to make horizontal and vertical arrays of characters from strings.
* Each cipher should implement the abstract AniNIX.Crypto.Cipher and may add unique functions.
A sample.txt file is provided for test purposes, and a Makefile contains all your compilation rules. The bash script will allow invocation on UNIX machines.

81
affine.csharp Normal file
View File

@ -0,0 +1,81 @@
using System;
using System.Linq;
using System.IO;
using System.Text;
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 Command() {return "affine";}
public Affine(Workbench w) : base (w) {}
public override String Encrypt(String workSpace,String inputText,String[] line) {
if (line == null || line.Length != 4) {
Console.Error.WriteLine("Malformed!");
return workSpace;
}
char[] changed = workSpace.ToCharArray();
try {
int a = Int32.Parse(line[2]);
try {
MultiplicativeInverse(a);
} catch (Exception e) {
Console.Error.WriteLine(String.Format("Value a <{0}> is not coprime to 26.\n{1}",a,e.Message));
return workSpace;
}
int b = Int32.Parse(line[3]);
for (int i = 0; i < changed.Length; i++) {
if (Char.IsLetter(changed[i])) {
int baseC = (Char.IsUpper(changed[i])) ? (int)'A' : (int)'a';
int modC = (int)changed[i] - baseC;
changed[i] = (char)(((a*modC+b)%26)+baseC);
}
}
} catch (Exception e) {
Console.Error.WriteLine(String.Format("Failed!\n{0}",e.Message));
return workSpace;
}
return new String(changed);
}
public int MultiplicativeInverse(int a) {
for (int x=1; x < 27; x++) {
if ((a*x)%26 == 1) {
Console.WriteLine(String.Format("Found Multiplicative Inverse of {0}",x));
return x;
}
}
throw new Exception("A is not coprime.");
}
public override String Decrypt(String workSpace,String inputText,String[] line) {
if (line == null || line.Length != 4) {
Console.Error.WriteLine("Malformed!");
return workSpace;
}
char[] changed = workSpace.ToCharArray();
try {
int a = Int32.Parse(line[2]);
int b = Int32.Parse(line[3]);
int multiinv = MultiplicativeInverse(a);
for (int i = 0; i < changed.Length; i++) {
if (Char.IsLetter(changed[i])) {
int baseC = (Char.IsUpper(changed[i])) ? (int)'A' : (int)'a';
int modC = (int)changed[i] - baseC;
int modResult = (multiinv * (modC-b))%26;
modResult = (modResult < 0) ? modResult+26 : modResult; // In case modResult is negative, add 26 back
changed[i] = (char)(modResult+baseC);
}
}
} catch (Exception e) {
Console.Error.WriteLine(String.Format("Failed!\n{0}",e.Message));
return workSpace;
}
return new String(changed);
}
}
}

248
analysis.csharp Normal file
View File

@ -0,0 +1,248 @@
using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
namespace AniNIX.Crypto {
public class Analysis : Cipher {
public override String Description() { return "Analysis tools"; }
public override String Command() { return "analysis"; }
public Analysis(Workbench w) : base (w) {}
public override String RunCommand(String workSpace, String inputText, String[] line) {
if (workSpace == null || inputText == null || line == null || line.Length < 2) {
Console.Error.WriteLine("Malformed!");
return workSpace;
}
switch (line[1]) {
case "freq":
Frequency(workSpace);
break;
case "freqinfo":
FrequencyInfo();
break;
case "one-to-one":
OneToOneQuery(workSpace,inputText);
break;
case "diff":
Diff(line);
break;
case "charinfo":
CharInfo(line);
break;
default:
GetHelp();
break;
}
return workSpace;
}
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");
}
public static Dictionary<String,int> FindFrequencies(String workSpace) {
Dictionary<String,int> frequencies = new Dictionary<String,int>();
for (int i = 0; i < workSpace.Length; i++) {
if (!Char.IsLetter(workSpace[i])) { continue; }
String charStr = String.Format("{0}",workSpace[i]);
if (frequencies.ContainsKey(charStr)) {
frequencies[charStr] = frequencies[charStr] + 1;
} else {
frequencies.Add(charStr,1);
}
}
return frequencies;
}
public static List<String> GetMostCommonLetters(String workSpace) {
List<KeyValuePair<String,int>> freqList = FindFrequencies(workSpace).ToList();
freqList.Sort((firstPair,nextPair)=>nextPair.Value.CompareTo(firstPair.Value));
List<String> returnL = new List<String>();
foreach (var item in freqList) {
returnL.Add(item.Key);
}
return returnL;
}
public static List<String> GetDoubles(String workSpace) {
List<String> theList = new List<String>();
for (int i=1; i<workSpace.Length; i++) {
if (workSpace[i] == workSpace[i-1] && !theList.Contains(workSpace[i].ToString())) {
theList.Add(workSpace[i].ToString());
}
}
return theList;
}
public static Dictionary<String,int> GetSubstrings(String workSpace, int length) {
Dictionary<string,int> theList = new Dictionary<string,int>();
for (int i=1; i<workSpace.Length-(length-1); i++) {
String segment = workSpace.Substring(i,length);
segment = Regex.Replace(segment, @"[^\w]", string.Empty);
if (segment.Length != length) continue;
if (theList.ContainsKey(segment)) {
theList[segment] += 1;
} else {
theList.Add(segment,1);
}
}
return theList;
}
public static Dictionary<String,int> FindWordsOfLength(int length,String[] bySpace) {
Dictionary<String,int> wordsFreq = new Dictionary<String,int>();
for (int i = 0; i < bySpace.Length; i++) {
if (bySpace[i].Length == length || (bySpace[i].Length == length+1 && Char.IsPunctuation(bySpace[i][length]))) {
if (Char.IsPunctuation(bySpace[i][bySpace[i].Length-1])) {
bySpace[i] = bySpace[i].Substring(0,bySpace[i].Length-1);
}
if (wordsFreq.ContainsKey(bySpace[i])) {
wordsFreq[bySpace[i]] += 1;
} else {
wordsFreq.Add(bySpace[i],1);
}
}
}
return wordsFreq;
}
public static List<String> Top(Dictionary<String,int> theList) {
List<KeyValuePair<string,int>> freqList = theList.ToList();
List<String> returnL = new List<String>();
freqList.Sort((firstPair,nextPair)=>nextPair.Value.CompareTo(firstPair.Value));
for (int i = 0; i < 5 && i < freqList.Count; i++) {
returnL.Add(freqList[i].Key);
}
return returnL;
}
public static void PrintOrdered(Dictionary<String,int> theList,String header) {
List<KeyValuePair<string,int>> freqList = theList.ToList();
freqList.Sort((firstPair,nextPair)=>nextPair.Value.CompareTo(firstPair.Value));
Console.Write(header);
for (int i = 0; i < 5 && i < freqList.Count; i++) {
Console.Write(String.Format("({0}){1} ",freqList[i].Key,freqList[i].Value));
}
Console.WriteLine("");
}
public static void PrintOrdered(List<String> theList,String header) {
Console.Write(header);
foreach (String str in theList) {
Console.Write(str);
Console.Write(" ");
}
Console.WriteLine();
}
public void Frequency(String workSpace) {
//Show the individual letter frequeuncy.
Console.ForegroundColor = ConsoleColor.Cyan;
PrintOrdered(FindFrequencies(workSpace),"Top letters by frequency: ");
//Show the doubled letters
Console.ForegroundColor = ConsoleColor.Green;
PrintOrdered(GetDoubles(workSpace),"The following letters are doubled in the workspace: ");
Console.ForegroundColor = ConsoleColor.Yellow;
PrintOrdered(GetSubstrings(workSpace,2),"Top substrings of length 2: ");
Console.ForegroundColor = ConsoleColor.Magenta;
PrintOrdered(GetSubstrings(workSpace,3),"Top substrings of length 3: ");
String[] bySpace = workSpace.Split(' ');
//Find the words of a given length
Console.ForegroundColor = ConsoleColor.White;
PrintOrdered(FindWordsOfLength(1,bySpace),"Words of length 1: ");
Console.ForegroundColor = ConsoleColor.Yellow;
PrintOrdered(FindWordsOfLength(2,bySpace),"Words of length 2: ");
Console.ForegroundColor = ConsoleColor.Magenta;
PrintOrdered(FindWordsOfLength(3,bySpace),"Words of length 3: ");
Console.ResetColor();
}
public void FrequencyInfo() {
// Thanks to http://norvig.com/mayzner.html for this info.
// By letter
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Letters by frequency:");
Console.WriteLine("E T A O I N S R H L D C U M F P G W Y B V K X J Q Z");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Possible doubles: LL EE SS OO TT FF RR NN PP CC BB MM GG UU ZZ AA");
// By Substring 2,3 characters in length
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Top sequences of N characters where N=...");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("2: th he in er an re on at en nd");
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("3: the and ing ion tio end ati for her ter");
// By word 1,2,3 chars in length
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Top words of length...");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("1: I a");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("2: of to in is it as be by on he");
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("3: the and for was not are his but had you");
Console.ResetColor();
}
public static void OneToOneQuery(String workSpace, String inputText) {
Dictionary<char,char> relation = new Dictionary<char,char>();
StringBuilder subKey = new StringBuilder();
StringBuilder encKey = new StringBuilder();
subKey.Append("True. These are one-to-one.\n");
subKey.Append("\nFinal-to-input key:\n");
subKey.Append("sub decrypt ");
encKey.Append("sub encrypt ");
for (int i = 0; i < workSpace.Length; i++) {
if (!Char.IsWhiteSpace(workSpace[i])) {
if (relation.ContainsKey(workSpace[i])) {
if (relation[workSpace[i]] != inputText[i]) {
Console.Error.WriteLine(String.Format("Character {0} repeated. These are not one-to-one.",workSpace[i]));
return;
}
} else {
relation.Add(workSpace[i],inputText[i]);
encKey.Append(String.Format("{0}={1} ",inputText[i],workSpace[i]));
subKey.Append(String.Format("{0}={1} ",workSpace[i],inputText[i]));
}
}
}
subKey.Append("\nInput-to-final key:");
Console.WriteLine(subKey.ToString());
Console.WriteLine(encKey.ToString());
}
public void Diff(String[] line) {
if (line.Length != 4 || line[2].Length != 1 || line[3].Length != 1) {
Console.Error.WriteLine("Bad formatting");
return;
}
char first = line[2][0];
char second = line[3][0];
Console.WriteLine(String.Format("These are different by {0}.",first-second));
}
public void CharInfo(String[] line) {
if (line == null || line.Length != 3 || line[2].Length != 1) {
Console.Error.WriteLine("Malformed");
return;
}
Console.WriteLine(String.Format("Character: {0}\nASCII Value: {1}",line[2][0],(int)line[2][0]));
if (Char.IsLetter(line[2][0])) {
Console.WriteLine(String.Format("Alphabet index: {0}",(Char.IsUpper(line[2][0])) ? (int)line[2][0] - (int)'A' : (int)line[2][0] - (int)'a'));
}
}
//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; }
public override String Decrypt(string workSpace,String ciphetText,String[] line) { return workSpace; }
}
}

7
bash.cryptoworkbench Normal file
View File

@ -0,0 +1,7 @@
#!/bin/bash
if [ "$1" != "" ]; then
time mono /opt/cryptoworkbench.exe "$1";
else
time mono /opt/cryptoworkbench.exe
fi
read

88
caesarian.csharp Normal file
View File

@ -0,0 +1,88 @@
using System;
using System.Linq;
using System.IO;
using System.Text;
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 Command() { return "caesar"; }
public Caesarian(Workbench w) : base (w) {}
public override String RunCommand(String workSpace,String inputText,String[] line) {
if (workSpace == null || line == null || line.Length < 2) {
Console.Error.WriteLine("Malformed request.");
return workSpace;
}
switch (line[1]) {
case "encrypt":
return Encrypt(workSpace,inputText,line);
case "decrypt":
return Decrypt(workSpace,inputText,line);
case "brute":
BruteForce(workSpace);
return workSpace;
default:
GetHelp();
return workSpace;
}
}
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.");
}
public override String Encrypt(String workSpace,String inputText,String[] line) {
if (line.Length != 3) {
Console.Error.WriteLine("Bad formatting");
return workSpace;
}
int rotation = 0;
try {
rotation = Int32.Parse(line[2]);
} catch (Exception e) {
Console.Error.WriteLine("Error in parsing rotation value -- should be numeric.");
Console.Error.WriteLine(e.Message);
return workSpace;
}
char[] modified = workSpace.ToCharArray();
for (int i = 0; i < modified.Length; i++) {
if (Char.IsLetter(modified[i])) {
int baseC;
int modC;
if (modified[i] < 'a') {
baseC = (int)'A';
modC = (int)modified[i] - (int)'A';
} else {
baseC = (int)'a';
modC = (int)modified[i] - (int)'a';
}
modC = (modC + rotation)%26;
//Debugging
//Console.Write(String.Format("Updating index {0} <{5}> val {1} base {2} mod {3} rotation {4} --to-- ",i,(int)modified[i],baseC,modC,rotation,modified[i]));
modified[i] = (char)(baseC+modC);
//Console.WriteLine(String.Format("<{0}> val {1}",modified[i],baseC+modC));
}
}
return new String(modified);
}
public override String Decrypt(String workSpace,String inputText,String[] line) {
return Encrypt(workSpace,inputText,line);
}
public void BruteForce(String workSpace) {
String[] line = new String[3];
line[0] = "rot";
line[1] = "encrypt";
for (int i=0; i<26; i++) {
line[2]=i.ToString();
Console.Write(String.Format("{0,2}: {1}",i,Encrypt(workSpace,null,line)));
}
}
}
}

9
captivecrypto.bash Normal file
View File

@ -0,0 +1,9 @@
#!/bin/bash
if [ $(pgrep -afc cryptoworkbench.exe) -gt 10 ]; then
echo All slots used -- you\'ll have to wait.
sleep 5
exit;
fi
exec bash -c "time mono /opt/cryptoworkbench.exe --blind; read"

117
chargrid.csharp Normal file
View File

@ -0,0 +1,117 @@
using System;
using System.Text;
namespace AniNIX.Crypto {
public class CharGrid {
protected char[][] theGrid;
///<Summary>
///Use this to even out grids so that columnar transpositions can be regular.
///</summary>
///<param name=input>The String to pad</param>
///<param name=width>How wide the grid should be</param>
///<returns>A paddded string</returns>
public static String RandPad(String input, int width) {
Random sRand = new Random();
int mod = input.Length%width;
if (mod == 0) return input;
char[] pad = new char[width-mod];
for (int i=0; i<pad.Length; i++) {
pad[i] = (char)(sRand.Next()%26 + (int)'A');
}
return input+(new String(pad));
}
private char[][] MakeGrid(String input, int width) {
int k=0;
int y=(input.Length%width == 0) ? input.Length/width : input.Length/width+1;
int remainingLength=input.Length;
char[][] newGrid = new char[y][];
for (int i=0; i < y; i++) {
newGrid[i] = new char[(remainingLength > width) ? width : remainingLength];
remainingLength -= width;
for (int j=0; j < newGrid[i].Length; j++) {
newGrid[i][j] = input[k++];
}
}
return newGrid;
}
private char[][] MakeVGrid(int length, int width) {
int y = (length%width == 0) ? length/width : length/width+1;
char[][] newGrid = new char[y][];
for (int i = 0; i < y; i++) {
newGrid[i] = new char[(length > width) ? width : length];
length -= width;
}
return newGrid;
}
/// <summary>
/// Make a horizontal grid from the input of certain width. Make regular if wanted.
/// </summary>
/// <param name=input>String to make from</param>
/// <param name=width>How wide a grid to make </param>
/// <param name=isRegular>Should random padding be added to make this not a jagged array</param>
public CharGrid(String input,int width,bool isRegular=false) {
if (isRegular) input = RandPad(input,width);
theGrid = MakeGrid(input,width);
}
/// <summary>
/// Make a vertical grid from the input of certain width. Make regular if wanted.
/// </summary>
/// <param name=input>String to make from</param>
/// <param name=width>How wide a grid to make </param>
/// <param name=order>What order should the columns be populated in?</param>
public CharGrid(String input,int width,int[] order) {
// Make a grid first.
theGrid = MakeVGrid(input.Length,width);
//Populate
int k = 0;
for (int j = 0; j < theGrid[0].Length; j++) {
for (int i = 0; i < theGrid.Length; i++) {
if (i != theGrid.Length-1 || order[j] < theGrid[i].Length) {
theGrid[i][order[j]] = input[k];
k++;
}
}
}
}
public override String ToString() {
StringBuilder sb = new StringBuilder();
sb.Append(String.Format("{0} {1} ------------->\n",theGrid.Length,theGrid[0].Length));
for (int j=0; j<theGrid.Length; j++) {
sb.Append("| ");
for (int i=0; i<theGrid[j].Length; i++) {
if (Char.IsLetter(theGrid[j][i])) {
sb.Append(String.Format("{0} ",theGrid[j][i]));
} else {
sb.Append(String.Format("A#{0} ",(int)theGrid[j][i]));
}
}
sb.AppendLine();
}
sb.Append("V\n");
return sb.ToString();
}
public char[][] ToArray() {
return theGrid;
}
// This is leftover in case you want to debug chargrid
/*public static void Main(String[] args) {
CharGrid cg = new CharGrid("helloiamanewcipher",5);
Console.Write(cg.ToString());
cg = new CharGrid("four",5,false);
Console.Write(cg.ToString());
return;
}*/
}
}

82
cipher.csharp Normal file
View File

@ -0,0 +1,82 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
namespace AniNIX.Crypto {
public abstract class Cipher {
//Cipher description to be set by each individual cipher.
public abstract String Description();
public abstract String Command();
/// <summary>
/// Create a new Cipher
/// </summary>
/// <returns>Cipher</returns>
public Cipher (Workbench w) {
string helpString = String.Format("{0} -- {1}\n",this.Command().PadRight(16),this.Description().Split('\n')[0]);
if (!w.HelpText.ToString().Contains(helpString)) {
w.HelpText.Append(helpString);
}
if (!w.SwitchCases.ContainsKey(this.Command())) {
w.SwitchCases.Add(this.Command(),this);
}
}
public Cipher() {
}
/// <summary>
/// We should be able to act on a workspace and command line. Most ciphers will sue the same syntax. Those that don't can override.
/// </summary>
/// <param name=workSpace>The current version of the text being worked on.</param>
/// <param name=line>The command sequence.</param>
/// <returns>The updated version of the workSpace</returns>
public virtual String RunCommand(String workSpace,String inputText,String[] line) {
if (workSpace == null || line == null || line.Length < 2) {
Console.Error.WriteLine("Malformed request.");
return workSpace;
}
switch (line[1]) {
case "encrypt":
return Encrypt(workSpace,inputText,line);
case "decrypt":
return Decrypt(workSpace,inputText,line);
case "help":
GetHelp();
return workSpace;
default:
Console.Error.WriteLine("Invalid command. Type help for more.");
return workSpace;
}
}
/// <summary>
/// Show the helptext for this cipher. By default, most ciphers will only have encrypt, decrypt, and help functions.
/// </summary>
/// <param name=line>This is the incoming line and we use it to get the cipher name</param>
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.");
}
/// <summary>
/// All ciphers must be able to encrypt a string.
/// </summary>
/// <param name=workSpace>The current version of the text being worked on.</param>
/// <param name=line>The command sequence.</param>
/// <returns>The updated version of the workSpace</returns>
public abstract String Encrypt(string workSpace,String ciphetText,String[] line);
/// <summary>
/// All ciphers must be able to decrypt a string.
/// </summary>
/// <param name=workSpace>The current version of the text being worked on.</param>
/// <param name=line>The command sequence.</param>
/// <returns>The updated version of the workSpace</returns>
public abstract String Decrypt(String workSpace,String inputText,String[] line);
}
}

View File

@ -0,0 +1,90 @@
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace AniNIX.Crypto {
public class ColumnTransposition : Cipher {
public override String Description() { return "Column Transposition cipher suite\nFormat is col <command> key1 [key2...]\nThe key format is any word to use for the transposition.\nThis cipher will use an irregular columnar transposition, without padding the input string.\n"; }
public override String Command() { return "col"; }
public ColumnTransposition(Workbench w) : base (w) {}
public ColumnTransposition() {}
private int[] GetColumnOrder(String key) {
List<char> orderList = new List<char>();
for (int i = 0; i < key.Length; i++) {
orderList.Add(key[i]);
}
orderList.Sort();
char[] charArr = orderList.ToArray();
int[] returnOrderIndexes = new int[key.Length];
Console.Write("Found key order: ");
for (int i = 0; i < key.Length; i++) {
for (int j = 0; j < charArr.Length; j++) {
if (key[i] == charArr[j]) {
Console.Write(String.Format("{0} ",j+1));
returnOrderIndexes[j] = i;
break;
}
}
}
Console.WriteLine("");
return returnOrderIndexes;
}
public override String Encrypt(String workSpace, String cipher, String[] line) {
if (line.Length < 3) {
Console.Error.WriteLine("Bad formatting.");
return workSpace;
}
String workSpaceNoNewline = workSpace.Replace("\n","");
char[] changed = workSpaceNoNewline.ToCharArray();
CharGrid cg = new CharGrid(workSpaceNoNewline,line[2].Length,false);
char[][] encryptionGrid = cg.ToArray();
int[] keyOrder = GetColumnOrder(line[2]);
Console.Write(cg.ToString());
int k = 0;
for (int j = 0; j < encryptionGrid[0].Length; j++) {
for (int i = 0; i < encryptionGrid.Length; i++) {
if (i != (encryptionGrid.Length-1) || keyOrder[j] < encryptionGrid[i].Length) {
changed[k] = encryptionGrid[i][keyOrder[j]];
k++;
}
}
}
String toReturn = new String(changed);
for (k = 0; k < workSpace.Length; k++) {
if (workSpace[k] == '\n') {
toReturn = toReturn.Insert(k,"\n");
}
}
return toReturn;
}
// TODO
public override String Decrypt(String workSpace, String cipher, String[] line) {
if (line.Length < 3) {
Console.Error.WriteLine("Bad formatting.");
return workSpace;
}
String workSpaceNoNewline = workSpace.Replace("\n","");
int[] keyOrder = GetColumnOrder(line[2]);
CharGrid cg = new CharGrid(workSpaceNoNewline,line[2].Length,keyOrder);
Console.Write(cg.ToString());
char[][] cgArray = cg.ToArray();
StringBuilder sb = new StringBuilder();
for (int i=0; i < cgArray.Length; i++) {
sb.Append(new String(cgArray[i]));
}
String toReturn = sb.ToString();
for (int i=0; i < workSpace.Length; i++) {
if (workSpace[i] == '\n') {
toReturn = toReturn.Insert(i,"\n");
}
}
return toReturn;
}
}
}

254
cryptoworkbench.csharp Normal file
View File

@ -0,0 +1,254 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using AniNIX.TheRaven;
namespace AniNIX.Crypto {
public class Workbench {
public string inputText { get; private set; }
public string workSpace { get; private set; }
public StringBuilder HelpText = new StringBuilder();
public Dictionary<String,Cipher> SwitchCases = new Dictionary<String,Cipher>();
private Substitution _sub;
private Analysis _analysis;
private Simple _simple;
private Caesarian _caesar;
private Affine _affine;
private Vigenere _vig;
private ColumnTransposition _col;
private Ubchi _ubchi;
private bool _isBlind = false;
private void ReadCipher(String[] line) {
if (line == null || line.Length !=2) {
Console.WriteLine("Please paste your ciphertext.");
string readLn = Console.ReadLine();
StringBuilder sb = new StringBuilder();
while (readLn != null && !String.IsNullOrWhiteSpace((readLn))) {
sb.AppendLine(readLn);
readLn=Console.ReadLine();
}
inputText = sb.ToString().Trim();
} else {
try {
StringBuilder sb = new StringBuilder();
StreamReader fileReader = new StreamReader(line[1]);
String lineR = fileReader.ReadLine();
while (lineR != null) {
sb.AppendLine(lineR);
lineR = fileReader.ReadLine();
}
fileReader.Dispose();
fileReader = null;
inputText = sb.ToString().Trim();
Console.WriteLine(String.Format("Read {0}",line[1]));
}
catch (Exception e) {
Console.Error.WriteLine(e.Message);
inputText = null;
}
}
workSpace = inputText;
}
public Workbench(string[] args) {
if (args.Length == 0) {
ReadCipher(null);
} else if (args.Length == 1) {
if (args[0].Equals("--blind")) {
this._isBlind = true;
ReadCipher(null);
} else {
String[] line = new String[2];
line[0] = "reread";
line[1] = args[0];
ReadCipher(line);
}
} else {
Console.Error.WriteLine("The only argument allowed is a filename containing the ciphertext or --blind to block filesystem access.");
System.Environment.Exit(1);
}
HelpText.Append("You can get help on any command by running \"<command> help\".\nSuppress printing the cipher with a trailing ;.\nAvailable commands:\n");
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("links -- show some helpful links\n");
HelpText.Append("help -- show this HelpText\n");
HelpText.Append("exit -- exit and show the result.\n");
HelpText.Append("quit -- alias of exit.\n");
_sub = new Substitution(this);
_analysis = new Analysis(this);
_simple = new Simple(this);
_caesar = new Caesarian(this);
_affine = new Affine(this);
_vig = new Vigenere(this);
_col = new ColumnTransposition(this);
_ubchi = new Ubchi(this);
}
public override String ToString() {
StringBuilder currentStatus = new StringBuilder();
currentStatus.Append("Input:\n");
currentStatus.Append(this.inputText);
currentStatus.Append("\n");
currentStatus.Append("Workspace:\n");
currentStatus.Append(this.workSpace);
return currentStatus.ToString();
}
public void Print() {
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Input:");
Console.ResetColor();
Console.WriteLine(this.inputText);
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Workspace:");
Console.ResetColor();
List<String> topletters = Analysis.GetMostCommonLetters(workSpace).Take(5).ToList();//cyan
List<String> bigrams = Analysis.Top(Analysis.GetSubstrings(workSpace,2)); //yellow
List<String> trigrams = Analysis.Top(Analysis.GetSubstrings(workSpace,3));//magenta
for (int i = 0; i < workSpace.Length; i++) {
if (i < workSpace.Length-1 && workSpace[i] == workSpace[i+1]) {
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(workSpace[i++]);
} else if (i < workSpace.Length-2 && trigrams.Contains(workSpace.Substring(i,3))) {
Console.ForegroundColor = ConsoleColor.Magenta;
Console.Write(workSpace[i++]);
Console.Write(workSpace[i++]);
} else if (i < workSpace.Length-1 && bigrams.Contains(workSpace.Substring(i,2))) {
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write(workSpace[i++]);
} else if (topletters.Contains(workSpace[i].ToString())) {
Console.ForegroundColor = ConsoleColor.Cyan;
}
Console.Write(workSpace[i]);
Console.ResetColor();
}
Console.WriteLine();
}
public static void HelpfulLinks() {
StringBuilder linksText = new StringBuilder();
linksText.Append("http://www.visca.com/regexdict/ -- RegEx word dictionary\n");
linksText.Append("http://rumkin.com/tools/cipher/ -- Cipher tools\n");
linksText.Append("http://norvig.com/mayzner.html -- Frequency analysis\n");
Console.Write(linksText.ToString());
}
public void WriteWorkspace(String workSpace, String[] line) {
if (line == null || line.Length != 2) {
Console.Error.WriteLine("Need a file.");
return;
}
try {
StreamWriter fileWriter = new StreamWriter(line[1],false);
fileWriter.WriteLine(workSpace);
fileWriter.Dispose();
fileWriter = null;
Console.WriteLine(String.Format("Wrote file {0}",line[1]));
} catch (Exception e) {
Console.WriteLine(String.Format("Couldn't write file.\n{0}",e.Message));
}
}
public void Run() {
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("### Welcome to the AniNIX::CryptoWorkbench ###");
Console.ResetColor();
try {
string command = "help";
string read = "help";
string[] line;
bool showCipher=true;
while (command != "exit" && command != "quit") {
foreach (String executable in read.Split(';')) {
if (String.IsNullOrWhiteSpace(executable)) {
showCipher = false;
continue;
}
showCipher = true;
line = executable.Trim().Split(' ');
command = line[0];
switch (command) {
case "reread":
if (!_isBlind) ReadCipher(line);
break;
case "write":
if (!_isBlind) WriteWorkspace(workSpace,line);
break;
case "reset":
this.workSpace = this.inputText;
Console.Clear();
Console.WriteLine("Reset.");
break;
case "links":
HelpfulLinks();
break;
case "regex":
try {
if (line.Length == 3) {
Console.Write(RavenExecute.Command(String.Format("bash /usr/local/src/CryptoWorkbench/regex-lookup.bash \"{0}\" \"{1}\"",line[1].Replace("\\","\\\\").Replace("$","\\$"),line[2].Replace("\\","\\\\").Replace("$","\\$"))));
} else if (line.Length == 2) {
Console.Write(RavenExecute.Command(String.Format("bash /usr/local/src/CryptoWorkbench/regex-lookup.bash \"{0}\"",line[1].Replace("\\","\\\\").Replace("$","\\$"))));
} else {
Console.Error.WriteLine("Need at least one search term.");
}
} catch (Exception e) {
Console.Error.WriteLine(e.ToString());
}
break;
case "help":
Console.WriteLine(HelpText.ToString());
break;
case "exit":
case "quit":
throw new Exception("");
default:
try {
workSpace = SwitchCases[command].RunCommand(this.workSpace,this.inputText,line);
} catch (Exception e) {
Console.Error.WriteLine("Command not found.");
}
break;
}
}
if (showCipher) Print();
Console.Write("\nWhat command would you like to execute?\n");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("|");
Console.ResetColor();
Console.Write("> ");
read = Console.ReadLine().Trim();
}
} catch (Exception e) {
Console.Error.WriteLine(e.Message);
}
finally {
Console.WriteLine("\nFinal result:");
this.Print();
}
}
public static void Main(string[] args) {
Workbench cw = new Workbench(args);
try {
cw.Run();
} catch (NullReferenceException e) {
Console.Error.WriteLine(String.Format("Caught {0}",e.GetType().ToString()));
}
}
}
}

23
newcipher.template Normal file
View File

@ -0,0 +1,23 @@
using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace AniNIX.Crypto {
public class Template : Cipher {
public override String Description() { return ; }
public override String Command() {return ;}
public Template(Workbench w) : base (w) {}
public override String Encrypt(String workSpace,String inputText,String[] line) {
return new String(changed);
}
public override String Decrypt(String workSpace,String inputText,String[] line) {
return new String(changed);
}
}
}

58
ravenexecute.csharp Normal file
View File

@ -0,0 +1,58 @@
using System;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
namespace AniNIX.TheRaven {
public static class RavenExecute {
/// <summary>
/// This method allows TheRaven to execute a command on the OS.
/// </summary>
/// <param name=command>The command string to run as the string argument to "bash -c 'command'"</param>
/// <param name=input>The effective replacement for the command's stdin</param
/// <return>The stdout of the command</return>
/// </summary>
public static String Command(String command, String input) {
//Sanitize inputs.
if (command.Contains("\'")) {
throw new Exception("Command strings cannot include \'.");
}
//Create process.
Process proc = new Process();
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.FileName = "/bin/bash";
proc.StartInfo.Arguments = String.Format("-c \'{0}\'",command);
proc.StartInfo.UseShellExecute=false;
//Redirect input
proc.StartInfo.RedirectStandardOutput=true;
proc.StartInfo.RedirectStandardInput=true;
//Start process
proc.Start();
//Add input and read output.
proc.StandardInput.Write(input);
proc.StandardInput.Close();
proc.WaitForExit();
if (proc.ExitCode != 0) {
throw new Exception(String.Format("Failed to exit command with return code {0}",proc.ExitCode));
}
String stdoutString = proc.StandardOutput.ReadToEnd();
//Close up and return
proc.Close();
return stdoutString;
}
//Add polymorphism to allow no stdin
public static String Command(String command) {
return Command(command,null);
}
}
}

14
regex-lookup.bash Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
if [ ! -x /usr/bin/curl ]; then
echo No curl installed!
exit 1
fi
if [ "$1" == "" ]; then
echo "Usage: $0 [search] [optional filter]"
exit 1
fi
export bashstr="$(printf "curl -s --data 'str=%s&fstr=%s&ifun=if&ccg=all&search=Search' http://www.visca.com/regexdict/" "$1" "$2")"
bash -c "$bashstr" | egrep 'any matches|yourdictionary' | cut -f 2 -d '>' | cut -f 1 -d '<'

3
sample.txt Normal file
View File

@ -0,0 +1,3 @@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
. ;:-_+=!@#$%^&*)({}[]\/?<>

90
simple.csharp Normal file
View File

@ -0,0 +1,90 @@
using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace AniNIX.Crypto {
public class Simple : Cipher {
//Cipher description to be set by each cipher.
public override String Description() { return "This is a suite of simple text ops."; }
public override String Command() { return "simple"; }
public Simple(Workbench w) : base (w) {}
/// <summary>
/// We should be able to act on a workspace and command line. Most ciphers will sue the same syntax. Those that don't can override.
/// </summary>
/// <param name=workSpace>The current version of the text being worked on.</param>
/// <param name=line>The command sequence.</param>
/// <returns>The updated version of the workSpace</returns>
public override String RunCommand(String workSpace,String inputText,String[] line) {
if (workSpace == null || line == null || line.Length < 2) {
Console.Error.WriteLine("Malformed request.");
return workSpace;
}
switch (line[1]) {
case "shiftup":
return ShiftUpper(workSpace);
case "shiftdown":
return ShiftLower(workSpace);
case "stripspace":
return StripSpaces(workSpace);
case "reverse":
return ReverseString(workSpace);
case "help":
GetHelp();
return workSpace;
default:
Console.Error.WriteLine("Invalid command. Type help for more.");
return workSpace;
}
}
/// <summary>
/// Show the helptext for this cipher. By default, most ciphers will only have encrypt, decrypt, and help functions.
/// </summary>
/// <param name=line>This is the incoming line and we use it to get the cipher name</param>
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.");
}
public String ShiftUpper(String workSpace) {
char[] changed = workSpace.ToCharArray();
for (int i = 0; i < changed.Length; i++) {
if (Char.IsLower(changed[i])) {
changed[i] = Char.ToUpper(changed[i]);
}
}
return new String(changed);
}
public String ShiftLower(String workSpace) {
char[] changed = workSpace.ToCharArray();
for (int i = 0; i < changed.Length; i++) {
if (Char.IsUpper(changed[i])) {
changed[i] = Char.ToLower(changed[i]);
}
}
return new String(changed);
}
public String StripSpaces(String workSpace) {
String changed = workSpace.Replace(" ","");
return changed;
}
public String ReverseString(String workSpace) {
char[] charArray = workSpace.ToCharArray();
Array.Reverse(charArray);
return new String(charArray);
}
//Simple 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; }
public override String Decrypt(string workSpace,String ciphetText,String[] line) { return workSpace; }
}
}

102
substitution.csharp Normal file
View File

@ -0,0 +1,102 @@
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace AniNIX.Crypto {
public class Substitution : Cipher {
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 Command() { return "sub"; }
public Substitution(Workbench w) : base (w) {}
/// <summary>
/// We should be able to act on a workspace and command line. Most ciphers will sue the same syntax. Those that don't can override.
/// </summary>
/// <param name=workSpace>The current version of the text being worked on.</param>
/// <param name=line>The command sequence.</param>
/// <returns>The updated version of the workSpace</returns>
public override String RunCommand(String workSpace,String inputText,String[] line) {
if (workSpace == null || line == null || line.Length < 2) {
Console.Error.WriteLine("Malformed request.");
return workSpace;
}
switch (line[1]) {
case "encrypt":
return Encrypt(workSpace,inputText,line);
case "decrypt":
return Decrypt(workSpace,inputText,line);
case "try-common":
return TryCommon(inputText);
case "help":
GetHelp();
return workSpace;
default:
Console.Error.WriteLine("Invalid command. Type help for more.");
return workSpace;
}
}
/// <summary>
/// Show the helptext for this cipher. By default, most ciphers will only have encrypt, decrypt, and help functions.
/// </summary>
/// <param name=line>This is the incoming line and we use it to get the cipher name</param>
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.");
}
public override String Encrypt(String workSpace, String cipher, String[] line) {
if (line.Length < 3) {
Console.Error.WriteLine("Bad formatting.");
return workSpace;
}
char[] changed = workSpace.ToCharArray();
for (int i=2; i<line.Length;i++) {
if (line[i].Length < 3 || line[i].Length%2 != 1 || line[i][line[i].Length/2] != '=') {
Console.Error.WriteLine("Bad substitution. Aborting.");
/* Console.Error.WriteLine(String.Format("Line length: {0}",line[i].Length));
* Console.Error.WriteLine(String.Format("Line mod 2: {0}",line[i].Length%2));
* Console.Error.WriteLine(String.Format("Line[length/2+1]: {0}",line[i][line[i].Length/2+1]));
*/
return workSpace;
}
for (int k = 0; k < line[i].Length/2; k++) {
char oldS = line[i].Substring(k,1)[0];
char newS = line[i].Substring(k+line[i].Length/2+1,1)[0];
Console.WriteLine(String.Format("Replacing cipher {0} to be workspace {1}",oldS,newS));
for (int j = 0; j < workSpace.Length; j++) {
if (cipher[j] == oldS) {
changed[j] = newS;
}
}
}
}
return new String(changed);
}
public override String Decrypt(String workSpace, String cipher, String[] line) {
return Encrypt(workSpace, cipher, line);
}
public String TryCommon(String workSpace) {
List<String> sortedChars = Analysis.GetMostCommonLetters(workSpace.ToLower());
char[] modified = workSpace.ToLower().ToCharArray();
char replaceChar;
for (int i = 0; i < modified.Length; i++) {
if (!Char.IsLetter(modified[i])) { continue; }
Console.WriteLine(String.Format("Character <{0}> occurs {1}st in frequency, corresponding with <{2}> -- replacing...",
modified[i],
sortedChars.IndexOf(modified[i].ToString()),
EngCommon[sortedChars.IndexOf(modified[i].ToString())]));
replaceChar = EngCommon[sortedChars.IndexOf(modified[i].ToString())];
replaceChar = (workSpace[i] == Char.ToLower(workSpace[i])) ? replaceChar : Char.ToUpper(replaceChar);
modified[i] = replaceChar;
}
return new String(modified);
}
}
}

39
ubchi.csharp Normal file
View File

@ -0,0 +1,39 @@
using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace AniNIX.Crypto {
public class Ubchi : Cipher {
public override String Description() { return "The Ubchi cipher\nThis is a regular double-transposition cipher -- it will add some garbage to the end of your string.\nKey format is any word to use for the transposition.\nNOTE: This does not completely match Rumkin, whose implementation is a little flawed."; }
public override String Command() { return "ubchi"; }
public Ubchi(Workbench w) : base (w) {}
private ColumnTransposition col = new ColumnTransposition();
public override String Encrypt(String workSpace,String inputText,String[] line) {
if (line == null || line.Length != 3) {
Console.Error.WriteLine("Malformed!");
return workSpace;
}
String changed = CharGrid.RandPad(workSpace,line[2].Length);
changed = col.Encrypt(changed,inputText,line);
changed = col.Encrypt(changed,inputText,line);
return changed;
}
public override String Decrypt(String workSpace,String inputText,String[] line) {
if (line == null || line.Length != 3) {
Console.Error.WriteLine("Malformed!");
return workSpace;
}
String changed = col.Decrypt(workSpace,inputText,line);
changed = col.Decrypt(changed,inputText,line);
return changed; // TODO Remove padding
}
}
}

77
vigenere.csharp Normal file
View File

@ -0,0 +1,77 @@
using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace AniNIX.Crypto {
public class Vigenere : Cipher {
public override String Description() { return "The basic Vigenere cipher\nKey format is any word to use for the passphrase"; }
public override String Command() { return "vig"; }
public Vigenere(Workbench w) : base (w) {}
public override String Encrypt(String workSpace,String inputText,String[] line) {
if (line == null || line.Length != 3) {
Console.Error.WriteLine("Malformed!");
return workSpace;
}
char[] changed = workSpace.ToCharArray();
try {
// line[2] is the key
int index = 0;
for (int i =0; i < line[2].Length; i++) {
if (!Char.IsLetter(line[2][i])) {
Console.Error.WriteLine("Keys must be only letters.");
return workSpace;
}
}
for (int i = 0; i < changed.Length; i++) {
if (Char.IsLetter(changed[i])) {
int baseC = (Char.IsUpper(changed[i])) ? (int)'A' : (int)'a';
int modC = (int)changed[i] - baseC;
int baseK = (Char.IsUpper(line[2][index])) ? (int)'A' : (int)'a';
int modK = (int)line[2][index] - baseK;
changed[i] = (char)(((modC+modK)%26)+baseC);
index = (index+1)%(line[2].Length);
}
}
} catch (Exception e) {
Console.Error.WriteLine(String.Format("Failed!\n{0}",e.Message));
return workSpace;
}
return new String(changed);
}
public override String Decrypt(String workSpace,String inputText,String[] line) {
if (line == null || line.Length != 3) {
Console.Error.WriteLine("Malformed!");
return workSpace;
}
char[] changed = workSpace.ToCharArray();
try {
// line[2] is the key
int index=0;
for (int i = 0; i < changed.Length; i++) {
if (Char.IsLetter(changed[i])) {
int baseC = (Char.IsUpper(changed[i])) ? (int)'A' : (int)'a';
int modC = (int)changed[i] - baseC;
int baseK = (Char.IsUpper(line[2][index])) ? (int)'A' : (int)'a';
int modK = (int)line[2][index] - baseK;
int modResult = (modC - modK)%26;
modResult = (modResult < 0) ? modResult+26 : modResult; // In case modResult is negative, add 26 back
changed[i] = (char)(modResult+baseC);
index = (index+1)%(line[2].Length);
}
}
} catch (Exception e) {
Console.Error.WriteLine(String.Format("Failed!\n{0}",e.Message));
return workSpace;
}
return new String(changed);
}
}
}