171 lines
5.4 KiB
Java
171 lines
5.4 KiB
Java
|
package net.knarcraft.bookswithoutborders;
|
||
|
|
||
|
import java.util.Random;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.HashMap;
|
||
|
|
||
|
public class GenenCrypt {
|
||
|
|
||
|
private final Random ranGen;
|
||
|
private final String[] bases;
|
||
|
private final ArrayList<String> originalCodonList;
|
||
|
private final ArrayList<String> shuffledCodonList;
|
||
|
private final String[] charList;
|
||
|
private final HashMap<String,String[]> codonTable;
|
||
|
private final HashMap<String, String> decryptTable;
|
||
|
private final String key;
|
||
|
|
||
|
public GenenCrypt(String key){
|
||
|
|
||
|
// define the initial, unshuffled codon list of 4 base codons
|
||
|
originalCodonList = new ArrayList<>();
|
||
|
bases = new String[]{"A", "T", "G", "C"};
|
||
|
for(int i = 0; i < 4; i++){
|
||
|
for(int j = 0; j < 4; j++){
|
||
|
for(int k = 0; k < 4; k++){
|
||
|
for(int l = 0; l < 4; l++){
|
||
|
originalCodonList.add("" + bases[i] + bases[j] + bases[k] + bases[l]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// make a random number generator with a seed based on the key
|
||
|
this.key = key;
|
||
|
long longKey = 0;
|
||
|
for(int i = 0; i < key.length(); i++){
|
||
|
longKey += (int)key.charAt(i);
|
||
|
}
|
||
|
ranGen = new java.util.Random(longKey);
|
||
|
|
||
|
// use the random number generator and the originalCodonList to make a shuffled list
|
||
|
shuffledCodonList = new ArrayList<>();
|
||
|
while(originalCodonList.size() > 0){
|
||
|
int index = ranGen.nextInt(originalCodonList.size());
|
||
|
shuffledCodonList.add(originalCodonList.get(index));
|
||
|
originalCodonList.remove(index);
|
||
|
}
|
||
|
|
||
|
// define the characters that can be encoded, 64 in total
|
||
|
// 26 capital letters
|
||
|
// 10 digits
|
||
|
// space, newline, and tab
|
||
|
// the symbols . , ? " ! @ # $ % ^ & * ( ) - + = / _ \ : ; < >
|
||
|
charList = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", " ", "\t", "\n", ".", ",", "?", "\"", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "+", "=", "/", "_", "\\", ":", ";", "<", ">", "|"};
|
||
|
|
||
|
// define the codon table to encode text
|
||
|
codonTable = new HashMap<>();
|
||
|
for(int i = 0; i < charList.length; i++){
|
||
|
String[] tempArray = new String[]{shuffledCodonList.get(4 * i), shuffledCodonList.get(4 * i + 1), shuffledCodonList.get(4 * i + 2), shuffledCodonList.get(4 * i + 3)};
|
||
|
//System.out.println(i);
|
||
|
codonTable.put(charList[i], tempArray);
|
||
|
}
|
||
|
|
||
|
// define the decryption table
|
||
|
decryptTable = new HashMap<>();
|
||
|
for(int i = 0; i < codonTable.size(); i++){
|
||
|
String s = charList[i];
|
||
|
String[] sa = codonTable.get(s);
|
||
|
decryptTable.put(sa[0], s);
|
||
|
decryptTable.put(sa[1], s);
|
||
|
decryptTable.put(sa[2], s);
|
||
|
decryptTable.put(sa[3], s);
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
public void printShuffledList(){
|
||
|
for (String s : shuffledCodonList) {
|
||
|
System.out.println(s);
|
||
|
}
|
||
|
}
|
||
|
public void printOriginalList(){
|
||
|
for (String s : originalCodonList) {
|
||
|
System.out.println(s);
|
||
|
}
|
||
|
}
|
||
|
public void printCodonTable(){
|
||
|
// print the codon table
|
||
|
for(int i = 0; i < codonTable.size(); i++){
|
||
|
String s = charList[i];
|
||
|
String[] sa = codonTable.get(s);
|
||
|
switch (s) {
|
||
|
case "\t":
|
||
|
System.out.println(i + "\t" + "\\t" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
||
|
break;
|
||
|
case "\n":
|
||
|
System.out.println(i + "\t" + "\\n" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
||
|
break;
|
||
|
case " ":
|
||
|
System.out.println(i + "\t" + "\" \"" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
||
|
break;
|
||
|
default:
|
||
|
System.out.println(i + "\t" + s + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public String encrypt(String input){
|
||
|
StringBuilder output = new StringBuilder();
|
||
|
for(int i = 0; i < input.length(); i++){
|
||
|
// insert junk bases
|
||
|
int offset = key.charAt(i % key.length());
|
||
|
StringBuilder junk = new StringBuilder();
|
||
|
for(int j = 0; j < offset; j++){
|
||
|
junk.append(bases[ranGen.nextInt(4)]);
|
||
|
}
|
||
|
output.append(junk);
|
||
|
int choose = ranGen.nextInt(4);
|
||
|
String s = ("" + input.charAt(i)).toUpperCase();
|
||
|
if(codonTable.containsKey(s)){
|
||
|
String[] sa = codonTable.get(s);
|
||
|
output.append(sa[choose]);
|
||
|
}
|
||
|
}
|
||
|
// add some junk bases to the end of the cipher text
|
||
|
int offset = key.charAt(input.length() % key.length());
|
||
|
StringBuilder junk = new StringBuilder();
|
||
|
for(int j = 0; j < offset; j++){
|
||
|
junk.append(bases[ranGen.nextInt(4)]);
|
||
|
}
|
||
|
output.append(junk);
|
||
|
return output.toString();
|
||
|
}
|
||
|
|
||
|
public String decrypt(String in){
|
||
|
String input = "" + in;
|
||
|
StringBuilder output = new StringBuilder();
|
||
|
int keyCount = 0;
|
||
|
int junk = key.charAt(keyCount % key.length());
|
||
|
while(input.length() > junk){
|
||
|
// cuts out the junk bases
|
||
|
input = input.substring(junk);
|
||
|
// get the codon, decrypt the codon, remove it from the input string
|
||
|
String codon = input.substring(0, 4);
|
||
|
output.append(decryptTable.get(codon));
|
||
|
input = input.substring(4);
|
||
|
// increment the key counter and update junk
|
||
|
keyCount++;
|
||
|
junk = key.charAt(keyCount % key.length());
|
||
|
}
|
||
|
return output.toString();
|
||
|
}
|
||
|
|
||
|
/*public static void main(String[] args){
|
||
|
GenenCrypt gc = new GenenCrypt("Another Key");
|
||
|
gc.printCodonTable();
|
||
|
System.out.println();
|
||
|
System.out.println();
|
||
|
System.out.println();
|
||
|
System.out.println("Encrypting the line \"Hello World!\"");
|
||
|
String encrypted = gc.encrypt("Hello World!");
|
||
|
System.out.println(encrypted);
|
||
|
System.out.println();
|
||
|
System.out.println("Decrypting the ciphertext");
|
||
|
System.out.println(gc.decrypt(encrypted));
|
||
|
|
||
|
}*/
|
||
|
}
|