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 originalCodonList; private final ArrayList shuffledCodonList; private final String[] charList; private final HashMap codonTable; private final HashMap 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)); }*/ }