171 lines
5.4 KiB
Java
Raw Normal View History

2021-08-26 20:18:37 +02:00
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));
}*/
}