More cleanup and adds some helper functions to new utility classes

This commit is contained in:
Kristian Knarvik 2021-08-28 18:28:50 +02:00
parent e1494440c8
commit cedb93be40
7 changed files with 386 additions and 277 deletions

View File

@ -14,6 +14,8 @@ import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
import net.knarcraft.bookswithoutborders.utility.FileHelper;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
@ -286,7 +288,7 @@ public class BooksWithoutBorders extends JavaPlugin {
sender.sendMessage(ChatColor.YELLOW + "Use: /bwb [Command]"); sender.sendMessage(ChatColor.YELLOW + "Use: /bwb [Command]");
sender.sendMessage(ChatColor.YELLOW + "[] denote parameters"); sender.sendMessage(ChatColor.YELLOW + "[] denote parameters");
if (BooksHavePrice()) { if (booksHavePrice()) {
if (bookPriceType != Material.AIR) if (bookPriceType != Material.AIR)
sender.sendMessage(ChatColor.RED + "[" + (int) bookPriceQuantity + " " + bookPriceType.toString() + "(s) are required to create a book]"); sender.sendMessage(ChatColor.RED + "[" + (int) bookPriceQuantity + " " + bookPriceType.toString() + "(s) are required to create a book]");
else else
@ -401,8 +403,7 @@ public class BooksWithoutBorders extends JavaPlugin {
} }
//Player only commands //Player only commands
if (sender instanceof Player) { if (sender instanceof Player player) {
Player player = (Player) sender;
if (args[0].equalsIgnoreCase("savePublic")) { if (args[0].equalsIgnoreCase("savePublic")) {
if (!sender.hasPermission("bookswithoutborders.savepublic")) { if (!sender.hasPermission("bookswithoutborders.savepublic")) {
@ -432,11 +433,10 @@ public class BooksWithoutBorders extends JavaPlugin {
if (((Player) sender).getItemInHand().getType() == Material.WRITTEN_BOOK || ((Player) sender).getItemInHand().getType() == Material.WRITABLE_BOOK) { if (((Player) sender).getItemInHand().getType() == Material.WRITTEN_BOOK || ((Player) sender).getItemInHand().getType() == Material.WRITABLE_BOOK) {
if (args.length == 2) { if (args.length == 2) {
saveBook((Player) sender, args[1], false); saveBook((Player) sender, args[1], false);
return true;
} else { } else {
saveBook((Player) sender, "false", false); saveBook((Player) sender, "false", false);
return true;
} }
return true;
} else { } else {
sender.sendMessage(ChatColor.RED + "You must be holding a written book or book and quill to save it!"); sender.sendMessage(ChatColor.RED + "You must be holding a written book or book and quill to save it!");
return false; return false;
@ -682,7 +682,7 @@ public class BooksWithoutBorders extends JavaPlugin {
return false; return false;
} }
if (BooksHavePrice() && if (booksHavePrice() &&
!sender.hasPermission("bookswithoutborders.bypassbookprice") && !sender.hasPermission("bookswithoutborders.bypassbookprice") &&
cannotPayForBookPrinting((Player) sender, Integer.parseInt(args[1]))) { cannotPayForBookPrinting((Player) sender, Integer.parseInt(args[1]))) {
return false; return false;
@ -731,9 +731,9 @@ public class BooksWithoutBorders extends JavaPlugin {
ItemStack eBook; ItemStack eBook;
if (args.length == 3) { if (args.length == 3) {
eBook = bookEncryption((Player) sender, args[1], args[2], ""); eBook = encryptBook((Player) sender, true, args[1], args[2], "");
} else { } else {
eBook = bookEncryption((Player) sender, args[1], "", ""); eBook = encryptBook((Player) sender, true, args[1], "", "");
} }
if (eBook != null) { if (eBook != null) {
@ -777,9 +777,9 @@ public class BooksWithoutBorders extends JavaPlugin {
ItemStack eBook; ItemStack eBook;
if (args.length == 4) { if (args.length == 4) {
eBook = bookEncryption((Player) sender, args[2], args[3], args[1]); eBook = encryptBook((Player) sender, true, args[2], args[3], args[1]);
} else { } else {
eBook = bookEncryption((Player) sender, args[2], "", args[1]); eBook = encryptBook((Player) sender, true, args[2], "", args[1]);
} }
if (eBook != null) { if (eBook != null) {
@ -828,11 +828,9 @@ public class BooksWithoutBorders extends JavaPlugin {
} }
} }
StringBuilder key = new StringBuilder();//converts user supplied key into integer form String key = EncryptionHelper.getNumberKeyFromStringKey(args[1]);
for (int x = 0; x < args[1].length(); x++)
key.append(Character.getNumericValue(Character.codePointAt(args[1], x)));
ItemStack book = eLoad(((Player) sender), key.toString(), true); ItemStack book = eLoad(((Player) sender), key, true);
if (book != null) { if (book != null) {
((Player) sender).setItemInHand(book); ((Player) sender).setItemInHand(book);
sender.sendMessage(ChatColor.GREEN + "Book decrypted!"); sender.sendMessage(ChatColor.GREEN + "Book decrypted!");
@ -1434,7 +1432,7 @@ public class BooksWithoutBorders extends JavaPlugin {
book.setItemMeta(bDat); book.setItemMeta(bDat);
book.setAmount(numCopies); book.setAmount(numCopies);
if (BooksHavePrice() && !sender.hasPermission("bookswithoutborders.bypassbookprice") && if (booksHavePrice() && !sender.hasPermission("bookswithoutborders.bypassbookprice") &&
(dir.equalsIgnoreCase("public") || dir.equalsIgnoreCase("player") || (dir.equalsIgnoreCase("public") || dir.equalsIgnoreCase("player") ||
dir.equalsIgnoreCase("")) && dir.equalsIgnoreCase("")) &&
cannotPayForBookPrinting((Player) sender, numCopies)) { cannotPayForBookPrinting((Player) sender, numCopies)) {
@ -1648,13 +1646,15 @@ public class BooksWithoutBorders extends JavaPlugin {
return rawPages; return rawPages;
} }
protected ItemStack bookEncryption(Player player, String key, String style, String groupName) { protected ItemStack encryptBook(Player player, boolean mainHand, String key, String style) {
StringBuilder ikey = new StringBuilder();//converts user supplied key into integer form return encryptBook(player, mainHand, key, style, "");
for (int x = 0; x < key.length(); x++) { }
ikey.append(Character.getNumericValue(Character.codePointAt(key, x)));
}
BookMeta book = (BookMeta) player.getItemInHand().getItemMeta(); protected ItemStack encryptBook(Player player, boolean mainHand, String key, String style, String groupName) {
//converts user supplied key into integer form
String integerKey = EncryptionHelper.getNumberKeyFromStringKey(key);
BookMeta book = getHeldBookMetadata(player, mainHand);
if (!book.hasPages()) { if (!book.hasPages()) {
player.sendMessage(ChatColor.RED + "Book is empty!"); player.sendMessage(ChatColor.RED + "Book is empty!");
@ -1662,121 +1662,129 @@ public class BooksWithoutBorders extends JavaPlugin {
} }
BookMeta nuMeta = null; BookMeta nuMeta = null;
boolean wasSaved = (groupName.equalsIgnoreCase("")) ? eSave(player, book, ikey.toString()) : (nuMeta = groupESave(player, book, ikey.toString(), groupName)) != null; boolean wasSaved = (groupName.equalsIgnoreCase("")) ? eSave(player, book, integerKey) : (nuMeta = groupESave(player, book, integerKey, groupName)) != null;
if (wasSaved) { if (wasSaved) {
ItemStack ecbook; ItemStack encryptedBook;
List<String> ecPages = new ArrayList<>(); List<String> encryptedPages = new ArrayList<>();
List<String> nuPages; List<String> nuPages;
if (style.equalsIgnoreCase("dna")) { if (style.equalsIgnoreCase("dna")) {
GenenCrypt gc = new GenenCrypt(ikey.substring(0, (ikey.length())));//Length used to be divided by /4 GenenCrypt gc = new GenenCrypt(integerKey.substring(0, (integerKey.length())));//Length used to be divided by /4
for (int x = 0; x < book.getPages().size(); x++) { for (int x = 0; x < book.getPages().size(); x++) {
ecPages.add(gc.encrypt(book.getPage(x + 1))); encryptedPages.add(gc.encrypt(book.getPage(x + 1)));
} }
} else if (style.equalsIgnoreCase("magic")) { } else if (style.equalsIgnoreCase("magic")) {
for (int i = 0; i < book.getPages().size(); i++) { for (int i = 0; i < book.getPages().size(); i++) {
String page = book.getPage(i + 1); String page = book.getPage(i + 1);
page = "ァk" + page.replace("", ""); page = "ァk" + page.replace("", "");
ecPages.add(page); encryptedPages.add(page);
} }
} else { } else {
SubstitutionCipher sc = new SubstitutionCipher(); SubstitutionCipher sc = new SubstitutionCipher();
for (int x = 0; x < book.getPages().size(); x++) { for (int x = 0; x < book.getPages().size(); x++) {
ecPages.add(sc.encrypt(book.getPage(x + 1), ikey.toString())); encryptedPages.add(sc.encrypt(book.getPage(x + 1), integerKey));
} }
} }
ecPages = pageFormat(ecPages); encryptedPages = pageFormat(encryptedPages);
nuPages = cleanList(ecPages); nuPages = cleanList(encryptedPages);
player.sendMessage(ChatColor.GREEN + "Book encrypted!"); player.sendMessage(ChatColor.GREEN + "Book encrypted!");
ecbook = new ItemStack(Material.WRITTEN_BOOK); encryptedBook = new ItemStack(Material.WRITTEN_BOOK);
book.setPages(nuPages); book.setPages(nuPages);
ecbook.setItemMeta(book); encryptedBook.setItemMeta(book);
ecbook.setAmount(player.getItemInHand().getAmount()); encryptedBook.setAmount(player.getItemInHand().getAmount());
if (nuMeta != null) if (nuMeta != null)
ecbook.setItemMeta(nuMeta); encryptedBook.setItemMeta(nuMeta);
return ecbook; return encryptedBook;
} }
return null; return null;
} }
protected void deleteBook(CommandSender sender, String fname, Boolean ispub) { /**
//checks if player is using list number to load * Deletes the given book
for (int x = 0; x < fname.length(); x++) { *
if (!Character.isDigit(fname.charAt(x))) { * @param sender <p>The sender of the command to delete the book</p>
break; * @param fileName <p>The file name of the book</p>
} * @param isPublic <p>Whether the book to delete is public or not</p>
if (x == fname.length() - 1 && Character.isDigit(fname.charAt(x)) && loadList.containsKey(sender.getName())) { */
if (Integer.parseInt(fname) <= loadList.get(sender.getName()).size()) { protected void deleteBook(CommandSender sender, String fileName, Boolean isPublic) {
fname = loadList.get(sender.getName()).get(Integer.parseInt(fname) - 1); //If the file name is an index of the load list, load the book
}
}
}
File file;
//TODO Convert namecheck into a method maybe
NameCheck:
{
//Extension is already present
if (fname.lastIndexOf(".") != -1) {
if (fname.substring(fname.lastIndexOf(".")).equals(".yml") || fname.substring(fname.lastIndexOf(".")).equals(".txt")) {
file = (ispub) ? new File(bookFolder + fname) :
new File(bookFolder + cleanString(sender.getName()) + SLASH + fname);
if (!file.isFile()) {
sender.sendMessage(ChatColor.RED + "Incorrect file name!");
return;
}
break NameCheck;
}
}
//No extension present
file = (ispub) ? new File(bookFolder + fname + ".yml") :
new File(bookFolder + cleanString(sender.getName()) + SLASH + fname + ".yml");
if (!file.isFile()) {
file = (ispub) ? new File(bookFolder + fname + ".txt") :
new File(bookFolder + cleanString(sender.getName()) + SLASH + fname + ".txt");
if (!file.isFile()) {
sender.sendMessage(ChatColor.RED + "Incorrect file name!");
return;
}
}
}
try { try {
file.delete(); int loadListIndex = Integer.parseInt(fileName);
} catch (Exception e) { String senderName = sender.getName();
sender.sendMessage(ChatColor.RED + "Deletion failed!"); if (loadList.containsKey(senderName) && loadListIndex <= loadList.get(senderName).size()) {
fileName = loadList.get(senderName).get(loadListIndex - 1);
}
} catch (NumberFormatException ignored) {
}
//Get the file to be deleted
File file;
if (isPublic) {
file = FileHelper.getBookFile(bookFolder + fileName);
} else {
file = FileHelper.getBookFile(bookFolder + cleanString(sender.getName()) + SLASH + fileName);
}
//Send message if no such file could be found
if (file == null) {
sender.sendMessage(ChatColor.RED + "Incorrect file name!");
return; return;
} }
sender.sendMessage(ChatColor.GREEN + "\"" + fname + "\" deleted successfully"); //Try to delete the file
try {
if (file.delete()) {
sender.sendMessage(ChatColor.GREEN + "\"" + fileName + "\" deleted successfully");
} else {
sender.sendMessage(ChatColor.RED + "Deletion failed without an exception!");
}
} catch (Exception e) {
sender.sendMessage(ChatColor.RED + "Deletion failed!");
}
} }
/** /**
* Unsigns the player's currently held book * Unsigns the player's currently held book
* @param player <p>The player holding the book</p> *
* @param player <p>The player holding the book</p>
* @param mainHand <p>Whether the player is holding the book in its main hand or its off hand</p> * @param mainHand <p>Whether the player is holding the book in its main hand or its off hand</p>
*/ */
protected void unSignHeldBook(Player player, boolean mainHand) { protected void unSignHeldBook(Player player, boolean mainHand) {
//Get the old book //Get the old book
BookMeta oldBook; BookMeta oldBook = getHeldBookMetadata(player, mainHand);
if (mainHand) {
oldBook = (BookMeta) player.getInventory().getItemInMainHand().getItemMeta();
} else {
oldBook = (BookMeta) player.getInventory().getItemInOffHand().getItemMeta();
}
//UnSign the book //UnSign the book
ItemStack newBook = new ItemStack(Material.WRITABLE_BOOK); ItemStack newBook = new ItemStack(Material.WRITABLE_BOOK);
newBook.setItemMeta(oldBook); newBook.setItemMeta(oldBook);
replaceHeldBook(player, newBook, mainHand);
}
/**
* Gets metadata about the player's held book
* @param player <p>The player holding the book</p>
* @param mainHand <p>Whether to get information about a book in the player's main hand or off hand</p>
* @return <p>Information about the held book</p>
*/
private BookMeta getHeldBookMetadata(Player player, boolean mainHand) {
if (mainHand) {
return (BookMeta) player.getInventory().getItemInMainHand().getItemMeta();
} else {
return (BookMeta) player.getInventory().getItemInOffHand().getItemMeta();
}
}
/**
* Replaces the player's held item
* @param player <p>The player to replace the item for</p>
* @param newBook <p>The new book the player should hold</p>
* @param mainHand <p>Whether to replace the item in the player's main hand or off hand</p>
*/
private void replaceHeldBook(Player player, ItemStack newBook, boolean mainHand) {
if (mainHand) { if (mainHand) {
player.getInventory().setItemInMainHand(newBook); player.getInventory().setItemInMainHand(newBook);
} else { } else {
@ -1784,13 +1792,19 @@ public class BooksWithoutBorders extends JavaPlugin {
} }
} }
protected boolean BooksHavePrice() { /**
* Checks whether books have a price for printing them
*
* @return <p>True if players need to pay for printing books</p>
*/
protected boolean booksHavePrice() {
return (bookPriceType != null && bookPriceQuantity > 0); return (bookPriceType != null && bookPriceQuantity > 0);
} }
/** /**
* Makes the player pay for printing a given number of books * Makes the player pay for printing a given number of books
* @param player <p>The player printing the books</p> *
* @param player <p>The player printing the books</p>
* @param numCopies <p>The number of copies the player is trying to print</p> * @param numCopies <p>The number of copies the player is trying to print</p>
* @return <p>True if the player cannot pay for the printing of the books</p> * @return <p>True if the player cannot pay for the printing of the books</p>
*/ */
@ -1816,7 +1830,8 @@ public class BooksWithoutBorders extends JavaPlugin {
/** /**
* Takes payment for printing a number of books by withdrawing the correct item * Takes payment for printing a number of books by withdrawing the correct item
* @param player <p>The player which needs to pay</p> *
* @param player <p>The player which needs to pay</p>
* @param itemCost <p>The number of items to pay</p> * @param itemCost <p>The number of items to pay</p>
*/ */
private void payForBookPrintingItem(Player player, int itemCost) { private void payForBookPrintingItem(Player player, int itemCost) {
@ -1839,8 +1854,9 @@ public class BooksWithoutBorders extends JavaPlugin {
/** /**
* Uses economy to take payment for printing a number of books * Uses economy to take payment for printing a number of books
* @param player <p>The player which needs to pay</p> *
* @param cost <p>The cost of the book printing</p> * @param player <p>The player which needs to pay</p>
* @param cost <p>The cost of the book printing</p>
* @param numCopies <p>The number of books the player is printing</p> * @param numCopies <p>The number of books the player is printing</p>
* @return <p>True if the player had the money and it has been withdrawn</p> * @return <p>True if the player had the money and it has been withdrawn</p>
*/ */
@ -1859,8 +1875,9 @@ public class BooksWithoutBorders extends JavaPlugin {
/** /**
* Checks whether the given player is the author of a given book * Checks whether the given player is the author of a given book
*
* @param player <p>The player to check</p> * @param player <p>The player to check</p>
* @param book <p>The book to check</p> * @param book <p>The book to check</p>
* @return <p>True if the player is the book's author</p> * @return <p>True if the player is the book's author</p>
*/ */
protected boolean isAuthor(Player player, BookMeta book) { protected boolean isAuthor(Player player, BookMeta book) {

View File

@ -4,6 +4,8 @@ import java.io.File;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
import net.knarcraft.bookswithoutborders.utility.FileHelper;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag; import org.bukkit.Tag;
@ -226,7 +228,7 @@ public class BooksWithoutBordersListener implements Listener {
//Tests if a full file name has been supplied and points to an actual file //Tests if a full file name has been supplied and points to an actual file
String signFile = bookFolder + lines[2] + lines[3]; String signFile = bookFolder + lines[2] + lines[3];
if (bookFileExists(signFile)) { if (FileHelper.bookFileExists(signFile)) {
markGiveSignValidity(event, true); markGiveSignValidity(event, true);
} else { } else {
if (isBookListIndex(lines[2])) { if (isBookListIndex(lines[2])) {
@ -258,17 +260,6 @@ public class BooksWithoutBordersListener implements Listener {
return false; return false;
} }
/**
* Checks if a file path points to an actual book
* @param bookFile <p>The path to a book</p>
* @return <p>True if the file exists and points to a book file</p>
*/
private boolean bookFileExists(String bookFile) {
return ((new File(bookFile).isFile() && (bookFile.toLowerCase().endsWith(".txt") ||
bookFile.toLowerCase().endsWith(".yml"))) || new File(bookFile + ".txt").isFile() ||
new File(bookFile + ".yml").isFile()) && !bookFile.contains("../") && !bookFile.contains("..\\");
}
/** /**
* Marks a give sign as valid or invalid * Marks a give sign as valid or invalid
* @param event <p>The event causing the creation of the give sign</p> * @param event <p>The event causing the creation of the give sign</p>
@ -390,9 +381,10 @@ public class BooksWithoutBordersListener implements Listener {
private void encryptHeldBookUsingSign(Sign sign, Material heldItemType, Player player, EquipmentSlot hand) { private void encryptHeldBookUsingSign(Sign sign, Material heldItemType, Player player, EquipmentSlot hand) {
ItemStack eBook; ItemStack eBook;
String[] lines = sign.getLines(); String[] lines = sign.getLines();
boolean mainHand = hand == EquipmentSlot.HAND;
if (heldItemType == Material.WRITTEN_BOOK) { if (heldItemType == Material.WRITTEN_BOOK) {
player.closeInventory(); player.closeInventory();
eBook = BooksWithoutBorders.bwb.bookEncryption(player, lines[2].substring(2), lines[3].substring(2), ""); eBook = BooksWithoutBorders.bwb.encryptBook(player, mainHand, lines[2].substring(2), lines[3].substring(2));
if (eBook != null) { if (eBook != null) {
player.getInventory().setItem(hand, eBook); player.getInventory().setItem(hand, eBook);
} }
@ -445,13 +437,10 @@ public class BooksWithoutBordersListener implements Listener {
player.closeInventory(); player.closeInventory();
//Converts user supplied key into integer form //Converts user supplied key into integer form
StringBuilder key = new StringBuilder();
String lineText = ChatColor.stripColor(sign.getLine(2)); String lineText = ChatColor.stripColor(sign.getLine(2));
for (int x = 0; x < lineText.length(); x++) { String key = EncryptionHelper.getNumberKeyFromStringKey(lineText);
key.append(Character.getNumericValue(Character.codePointAt(lineText, x)));
}
ItemStack book = BooksWithoutBorders.bwb.eLoad(player, key.toString(), false); ItemStack book = BooksWithoutBorders.bwb.eLoad(player, key, false);
if (book != null) { if (book != null) {
player.getInventory().setItem(hand, book); player.getInventory().setItem(hand, book);
player.sendMessage(ChatColor.GREEN + "Book decrypted!"); player.sendMessage(ChatColor.GREEN + "Book decrypted!");

View File

@ -4,167 +4,178 @@ import java.util.Random;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
/**
* Case-insensitive gene-based encryption
*
* <p>Not sure where this was gotten from, but it does exist at
* <a href="https://crypto.stackexchange.com/questions/11614/how-do-i-test-my-encryption-absolute-amateur">Stack Exchange</a>.</p>
*/
public class GenenCrypt { public class GenenCrypt {
private final Random ranGen; private final Random ranGen;
private final String[] bases; private final String[] bases;
private final ArrayList<String> originalCodonList; private final ArrayList<String> originalCodonList;
private final ArrayList<String> shuffledCodonList; private final ArrayList<String> shuffledCodonList;
private final String[] charList; private final String[] charList;
private final HashMap<String,String[]> codonTable; private final HashMap<String, String[]> codonTable;
private final HashMap<String, String> decryptTable; private final HashMap<String, String> decryptTable;
private final String key; private final String key;
public GenenCrypt(String key){ /**
* Instantiates a new GenenCrypt
// define the initial, unshuffled codon list of 4 base codons * @param key <p>The key used to generate the codon table</p>
originalCodonList = new ArrayList<>(); */
bases = new String[]{"A", "T", "G", "C"}; public GenenCrypt(String key) {
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){ // define the initial, unshuffled codon list of 4 base codons
for(int k = 0; k < 4; k++){ originalCodonList = new ArrayList<>();
for(int l = 0; l < 4; l++){ bases = new String[]{"A", "T", "G", "C"};
originalCodonList.add("" + bases[i] + bases[j] + bases[k] + bases[l]); 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); // make a random number generator with a seed based on the key
} this.key = key;
ranGen = new java.util.Random(longKey); long longKey = 0;
for (int i = 0; i < key.length(); i++) {
// use the random number generator and the originalCodonList to make a shuffled list longKey += (int) key.charAt(i);
shuffledCodonList = new ArrayList<>(); }
while(originalCodonList.size() > 0){ ranGen = new java.util.Random(longKey);
int index = ranGen.nextInt(originalCodonList.size());
shuffledCodonList.add(originalCodonList.get(index)); // use the random number generator and the originalCodonList to make a shuffled list
originalCodonList.remove(index); shuffledCodonList = new ArrayList<>();
} while (originalCodonList.size() > 0) {
int index = ranGen.nextInt(originalCodonList.size());
// define the characters that can be encoded, 64 in total shuffledCodonList.add(originalCodonList.get(index));
// 26 capital letters originalCodonList.remove(index);
// 10 digits }
// space, newline, and tab
// the symbols . , ? " ! @ # $ % ^ & * ( ) - + = / _ \ : ; < > // define the characters that can be encoded, 64 in total
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", ".", ",", "?", "\"", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "+", "=", "/", "_", "\\", ":", ";", "<", ">", "|"}; // 26 capital letters
// 10 digits
// define the codon table to encode text // space, newline, and tab
codonTable = new HashMap<>(); // the symbols . , ? " ! @ # $ % ^ & * ( ) - + = / _ \ : ; < >
for(int i = 0; i < charList.length; i++){ charList = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
String[] tempArray = new String[]{shuffledCodonList.get(4 * i), shuffledCodonList.get(4 * i + 1), shuffledCodonList.get(4 * i + 2), shuffledCodonList.get(4 * i + 3)}; "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", " ",
//System.out.println(i); "\t", "\n", ".", ",", "?", "\"", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "+", "=", "/",
codonTable.put(charList[i], tempArray); "_", "\\", ":", ";", "<", ">", "|"};
}
// define the codon table to encode text
// define the decryption table codonTable = new HashMap<>();
decryptTable = new HashMap<>(); for (int i = 0; i < charList.length; i++) {
for(int i = 0; i < codonTable.size(); i++){ String[] tempArray = new String[]{shuffledCodonList.get(4 * i), shuffledCodonList.get(4 * i + 1),
String s = charList[i]; shuffledCodonList.get(4 * i + 2), shuffledCodonList.get(4 * i + 3)};
String[] sa = codonTable.get(s); //System.out.println(i);
decryptTable.put(sa[0], s); codonTable.put(charList[i], tempArray);
decryptTable.put(sa[1], s); }
decryptTable.put(sa[2], s);
decryptTable.put(sa[3], s); // 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);
public void printShuffledList(){ decryptTable.put(sa[1], s);
for (String s : shuffledCodonList) { decryptTable.put(sa[2], s);
System.out.println(s); decryptTable.put(sa[3], s);
} }
}
public void printOriginalList(){
for (String s : originalCodonList) { }
System.out.println(s);
} /**
} * Prints the shuffled codon list used for generating the codon table
public void printCodonTable(){ */
// print the codon table public void printShuffledList() {
for(int i = 0; i < codonTable.size(); i++){ for (String s : shuffledCodonList) {
String s = charList[i]; System.out.println(s);
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; * Prints the original codon list before it was shuffled
case "\n": */
System.out.println(i + "\t" + "\\n" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]); public void printOriginalList() {
break; for (String s : originalCodonList) {
case " ": System.out.println(s);
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; * Prints the codon table used for encryption and decryption
} */
} public void printCodonTable() {
} // print the codon table
for (int i = 0; i < codonTable.size(); i++) {
public String encrypt(String input){ String s = charList[i];
StringBuilder output = new StringBuilder(); String[] sa = codonTable.get(s);
for(int i = 0; i < input.length(); i++){ switch (s) {
// insert junk bases case "\t" -> System.out.println(i + "\t" + "\\t" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
int offset = key.charAt(i % key.length()); case "\n" -> System.out.println(i + "\t" + "\\n" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
StringBuilder junk = new StringBuilder(); case " " -> System.out.println(i + "\t" + "\" \"" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
for(int j = 0; j < offset; j++){ default -> System.out.println(i + "\t" + s + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
junk.append(bases[ranGen.nextInt(4)]); }
} }
output.append(junk); }
int choose = ranGen.nextInt(4);
String s = ("" + input.charAt(i)).toUpperCase(); /**
if(codonTable.containsKey(s)){ * Encrypts some input
String[] sa = codonTable.get(s); * @param input <p>The input to encrypt</p>
output.append(sa[choose]); * @return <p>The encrypted input</p>
} */
} public String encrypt(String input) {
// add some junk bases to the end of the cipher text StringBuilder output = new StringBuilder();
int offset = key.charAt(input.length() % key.length()); for (int i = 0; i < input.length(); i++) {
StringBuilder junk = new StringBuilder(); // insert junk bases
for(int j = 0; j < offset; j++){ int offset = key.charAt(i % key.length());
junk.append(bases[ranGen.nextInt(4)]); StringBuilder junk = new StringBuilder();
} for (int j = 0; j < offset; j++) {
output.append(junk); junk.append(bases[ranGen.nextInt(4)]);
return output.toString(); }
} output.append(junk);
int choose = ranGen.nextInt(4);
public String decrypt(String in){ String s = ("" + input.charAt(i)).toUpperCase();
String input = "" + in; if (codonTable.containsKey(s)) {
StringBuilder output = new StringBuilder(); String[] sa = codonTable.get(s);
int keyCount = 0; output.append(sa[choose]);
int junk = key.charAt(keyCount % key.length()); }
while(input.length() > junk){ }
// cuts out the junk bases // add some junk bases to the end of the cipher text
input = input.substring(junk); int offset = key.charAt(input.length() % key.length());
// get the codon, decrypt the codon, remove it from the input string StringBuilder junk = new StringBuilder();
String codon = input.substring(0, 4); for (int j = 0; j < offset; j++) {
output.append(decryptTable.get(codon)); junk.append(bases[ranGen.nextInt(4)]);
input = input.substring(4); }
// increment the key counter and update junk output.append(junk);
keyCount++; return output.toString();
junk = key.charAt(keyCount % key.length()); }
}
return output.toString(); /**
} * Decrypts some input
* @param input <p>The input to decrypt</p>
/*public static void main(String[] args){ * @return <p>The decrypted input</p>
GenenCrypt gc = new GenenCrypt("Another Key"); */
gc.printCodonTable(); public String decrypt(String input) {
System.out.println(); StringBuilder output = new StringBuilder();
System.out.println(); int keyCount = 0;
System.out.println(); int junk = key.charAt(0);
System.out.println("Encrypting the line \"Hello World!\""); while (input.length() > junk) {
String encrypted = gc.encrypt("Hello World!"); // cuts out the junk bases
System.out.println(encrypted); input = input.substring(junk);
System.out.println(); // get the codon, decrypt the codon, remove it from the input string
System.out.println("Decrypting the ciphertext"); String codon = input.substring(0, 4);
System.out.println(gc.decrypt(encrypted)); 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();
}
} }

View File

@ -0,0 +1,18 @@
package net.knarcraft.bookswithoutborders.utility;
public class EncryptionHelper {
/**
* Transforms a string key/password into its numerical values
* @param key <p>The key to transform</p>
* @return <p>The numbers representing the key's characters</p>
*/
public static String getNumberKeyFromStringKey(String key) {
StringBuilder integerKey = new StringBuilder();
for (int x = 0; x < key.length(); x++) {
integerKey.append(Character.getNumericValue(Character.codePointAt(key, x)));
}
return integerKey.toString();
}
}

View File

@ -0,0 +1,41 @@
package net.knarcraft.bookswithoutborders.utility;
import java.io.File;
public class FileHelper {
/**
* Checks if a file path points to an actual book
* @param bookFile <p>The path to a book</p>
* @return <p>True if the file exists and points to a book file</p>
*/
public static boolean bookFileExists(String bookFile) {
return ((new File(bookFile).isFile() && (bookFile.endsWith(".txt") ||
bookFile.endsWith(".yml"))) || new File(bookFile + ".txt").isFile() ||
new File(bookFile + ".yml").isFile()) && !bookFile.contains("../") && !bookFile.contains("..\\");
}
public static File getBookFile(String bookPath) {
if (!bookFileExists(bookPath)) {
return null;
}
File bookFile = new File(bookPath);
if (bookFile.exists()) {
return bookFile;
}
File bookFileYml = new File(bookPath + ".yml");
if (bookFileYml.exists()) {
return bookFileYml;
}
File bookFileTxt = new File(bookPath + ".txt");
if (bookFileTxt.exists()) {
return bookFileTxt;
}
return null;
}
}

View File

@ -0,0 +1,17 @@
package net.knarcraft.bookswithoutborders;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class GenenCryptTest {
@Test
public void encryptDecryptTest() {
GenenCrypt gc = new GenenCrypt("Another Key");
gc.printCodonTable();
String encrypted = gc.encrypt("Hello World!");
assertEquals("HELLO WORLD!", gc.decrypt(encrypted));
}
}

View File

@ -0,0 +1,16 @@
package net.knarcraft.bookswithoutborders.util;
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class EncryptionHelperTest {
@Test
public void getNumberKeyFromStringKey() {
String numberKey = EncryptionHelper.getNumberKeyFromStringKey("hello");
assertEquals("1714212124", numberKey);
}
}