Need feedback for my program.
Hello
I have created a little program that can encrypt and decrypt text file.
How the encryption works:
Every character in the text file will be replaced with an encryption code that looks like this |**********|, * is either $,§ or ¥. The program also uses a key to encrypt and decrypt file.
It will also append an special type of encryption code to the end of each line that will be replaced with \n when decrypting.
I am looking for feedback.
What could I have done better?
Is there a group of code, or just a line, that could be replaced with an other type of code?
How is my code? i e Is it a mess? etc
How is my commenting?
Known issues, the encryption and decryption algorithm could be better, example if the text file is to large, program will probably get heap space exception.
Please, try the program first by launching Mainprogram.class. The rar file also contains the source code, but in case someone dont want to download, I paste the codes here to
Crypting.rar
Code:
package pjjava.crypt;
import java.util.*;
import java.io.*;
class Mainprogram
{
//These are available for the whole class
static SuperObj sobj = new SuperObj ();
static Scanner in = new Scanner (System.in);
public static void main (String[] args) throws Exception
{
System.out.println ("Menu:");
System.out.println ("1. Create and load key\n" +
"2. Load existing key\n" +
"3. Load file\n" +
"4. Encrypt file\n" +
"5. Decrypt file\n" +
"6. Help\n" +
"7. Exit");
while (true)
{
selectOption ();
}
}
static void selectOption () throws Exception
{
System.out.println ("Please choose what option you want to do:");
byte option = controlNumber ();
if (option == 1)
sobj.setKey (CryptMethods.produceKey ());
if (option == 2)//Enter key path, load it, and then check it it is the actuall key
{
String keypath = "";
try
{
keypath = CryptMethods.loadExtFile (2);
}
catch (Exception e)
{
System.out.println ("Thats not a key");
return;
}
sobj.setKey (CryptMethods.filePathTo2DArray (keypath));
System.out.println ("Key was succesfully set!");
}
if (option == 3)//Load a file, no control needed.
{
sobj.setFilePath (CryptMethods.loadExtFile (1));
System.out.println ("File was succesfully set!");
}
if (option == 4)
{
if (!sobj.FileLoaded ())
{
System.out.println ("You must load key and file before you can encrypt it.");
return;
}
sobj.encryptFile ();
}
if (option == 5)
{
if (!sobj.FileLoaded ())
{
System.out.println ("You must load key and file before you can decrypt it.");
return;
}
sobj.decryptFile ();
}
if (option == 6)
System.out.println ("When key is created, it will placed in the root. Encrypted and decrypted files will be placed in the same folder as their source files.\n" +
"The name of the key and the files must be in a-z and 0-9, or they wont be read by the program. \n" +
"This program will encrypt all ANSI characters, the charaters that are not in the ANSI list will be lost.");
if (option == 7)
System.exit (0);
return;
}
private static byte controlNumber ()
{
byte number = 0;
while (true)
{
try
{
number = in.nextByte ();
in.nextLine ();
//If a valid number is entered above, an other check start to see if the number is between 1 to 7.
if (!(number >= 1 && number <= 7))
throw new Exception ();
break;
}
catch (Exception e)
{
System.out.println ("Not an option, try again!");
in.nextLine (); //Clean the buffert, or program will be stuck in a infinite loop.
}
}
return number;
}
}
Code:
package pjjava.crypt;
import java.util.*;
import java.io.*;
class SuperObj
{
private String[][] key;
private String filePath;
SuperObj ()
{
key = null;
filePath = null;
}
void setKey (String key[][])//Chaning key will also change this.key, since they point to the same place in the computer memory, but this wont be an issue in this program.
{
this.key = key;
}
void setFilePath (String filePath)
{
this.filePath = filePath;
}
void encryptFile () throws Exception //Call an other method to do the dirty job
{
CryptMethods.encryptFile (this.key, this.filePath);
}
void decryptFile () throws Exception //Call an other method to do the dirty job
{
CryptMethods.decryptFile (this.key, this.filePath);
}
boolean FileLoaded () //Check so if the key or a file is loaded, if they are, return true
{
boolean b = false;
if (this.key == null || this.filePath == null)
b = false;
else
b = true;
return b;
}
}
Code:
package pjjava.crypt;
import java.util.*;
import java.io.*;
import java.lang.*;
class CryptMethods
{
static Scanner in = new Scanner (System.in);
private static final char[] theChars =
{'!', '\'', '#', '¤', '%', '&', '/', '(', ')',
'=', '?', '`', '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', '+', '´', '‰', '½', '@',
'£', '„', '€', '{', '[', ']', '}', '\\', 'q',
'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',
'å', '¨', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U',
'I', 'O', 'P', 'Å', '^', '~', 'a', 's', 'd',
'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', '\'',
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L',
'Ö', 'Ä', '*', '<', 'z', 'x', 'c', 'v', 'b',
'n', 'm', ',', '.', '-', '>', 'Z', 'X', 'C',
'V', 'B', 'N', 'M', ';', ':', '_', '…', 'µ',
'ª', '©', '¨', '¦', 'Œ', '¢', '¡', ' ', ' ',
'«', '¬', '*', '®', '¯', '°', '±', '²', '³',
'¶', '·', '¸', '¹', 'º', '»', '¼', '¾', '¿',
'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È',
'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ',
'Ò', 'Ó', 'Ô', 'Õ', 'Ö', '×', 'Ø', 'Ù', 'Ú',
'Û', 'Ü', 'Ý', 'Þ', 'ß', 'à', 'á', 'â', 'ã',
'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì',
'í', 'î', 'ï', 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ',
'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ',
'ÿ', '†', 'ƒ', '‡', 'Š', 'Ž', '™'}; //Can not contain |, §. $ and ¥, or the crypting process will fuck up
//Feel free to edit this array or add new elemnts to it. Just remeber to create a new key.
static String loadExtFile (int helpNum) throws Exception //Load-Existing-File. Enter files path, a check to see if it is actually a file, and return the path
{
if (helpNum == 1)
System.out.println ("Please enter the file path including the filenamn and extension:\n" +
"Example: C:\\My Documents\\hello.txt");
if (helpNum == 2)
System.out.println ("Please enter the key path including the filenamn and extension:\n" +
"Example: C:\\Program\\Java\\cryptKey.kry");
String filePath = "";
while (true)
{
filePath = in.nextLine ();
File fil = new File (filePath);
if (!fil.exists() || !fil.isFile())
{
System.out.println ("Invalid file, please try again");
continue;
}
break;
}
//This code check so that the key loaded is actually the key
if (helpNum == 2) //If user try to load a key and not the file
{
if (getNumberOfLines (filePath) != (theChars.length + 2) * 100)
throw new Exception ();
}
return filePath;
}
static String[][] produceKey () throws Exception
{
//User info
System.out.println ("Generating key, please wait...");
StringBuilder[] format = new StringBuilder[(theChars.length + 2) * 100];
char[] encryptChar = {'§', '¥', '$'};
//All the "a" characters will be replaced with one of the chars in encryptChar array.
for (int q = 0; q < format.length; q++)
format[q] = new StringBuilder ("|aaaaaaaaaa|");
//Generate the format
FLoop:
for (int i = 0; i < format.length; i++)
{
for (int j = 1; j < 11; j++)
format[i].setCharAt (j, encryptChar[(int) (3 * Math.random())]);
//This little algorithm check so there is no duplicates in the array
for (int p = 0; p < i; p++)
{
if (format[i].toString ().equals (format[p].toString ()))
{
i--;
continue FLoop;
}
}
}
//Print the key(format array) into a file
File fil = new File ("/cryptKey.kry"); //Paste the new key in root
PrintWriter fout = new PrintWriter (fil);
for (int p = 0; p < format.length; p++)
fout.println (format[p].toString ());
fout.close ();
//User info
System.out.println ("Key was succesfully set!");
return filePathTo2DArray ("/cryptKey.kry");
}
static String[][] filePathTo2DArray (String keyPath) throws Exception //Read the key from the PC and return it as an 2D string array
{
File fi = new File (keyPath);
FileReader fil = new FileReader (fi);
BufferedReader fout = new BufferedReader (fil);
String[][] key = new String[theChars.length + 2][100];
for (int i = 0; i < theChars.length + 2; i++)
{
for (int j = 0; j < 100; j++)
{
key[i][j] = new String (fout.readLine ());
}
}
fil.close ();
fout.close ();
return key;
}
static void encryptFile (String key[][], String filePath) throws Exception
{
//User info
System.out.println ("Please wait while the file being encrypted");
//Read the file
File fi = new File (filePath);
FileReader fil = new FileReader (fi);
BufferedReader fout = new BufferedReader (fil);
//Copy the content of the file to this array
StringBuilder[] theFile = new StringBuilder[getNumberOfLines(filePath)];
for (int i = 0; i < theFile.length; i++)
theFile[i] = new StringBuilder (fout.readLine ());
fil.close ();
fout.close ();
//These characters will be used as encrypt format so they cant exist while the encrypting text. When decrypting, they will be replaced with their correct char.
for (int r = 0; r < theFile.length; r++)
{
String temp = theFile[r].toString ().replace ("|", "[·vt]").
replace ("$", "[·dl]").
replace ("§", "[·es]").
replace ("¥", "[·yy]");
theFile[r] = new StringBuilder (temp);
}
//Encrypt all the chars that are in theChars array
for (int z = 0; z < theFile.length; z++)
{
for (int v = 0; v < theChars.length; v++)
{
String tempChar = theChars[v] + "";
String tempString = theFile[z].toString ().replace (tempChar, key[v][(int) (100 * Math.random())]);
theFile[z] = new StringBuilder (tempString);
}
}
//All the chars in theChars are now encrypted. But that does not mean all the chars are encrypted, the chars that are not on theChars array are not supported and still not encrypted.
//In the code below, is it time to encrypt them aswell with theChars.length + 1. These will be lost later while decrypting
for (int a = 0; a < theFile.length; a++)
{
for (int b = 0; b < theFile[a].length (); b++)
{
char cc = (char) theFile[a].charAt (b);
if (cc != '|' &&
cc != '$' &&
cc != '§' &&
cc != '¥')
theFile[a] = theFile[a].deleteCharAt (b).insert (b, key[theChars.length][(int) (100 * Math.random())]);//Since arrays start with index 0, the first dimension is the "+ 1"
}
}
//Append theChars.length + 2 to every line, this will be replaced with \n when decrypting
for (int e = 0; e < theFile.length; e++)
theFile[e] = theFile[e].append (key[theChars.length + 1][(int) (100 * Math.random())]);//Since arrays start with index 0, the first dimension is the "+ 2"
//Print the encrypted text to an file
FileWriter fw = new FileWriter (getOutputName (filePath, true));
BufferedWriter writeout = new BufferedWriter (fw);
for (int z = 0; z < theFile.length; z++)
{
writeout.write (theFile[z].toString ());
writeout.newLine ();
}
writeout.close ();
fw.close ();
//User info
System.out.println ("File encrypted.");
}
static void decryptFile (String key[][], String filePath) throws Exception
{
//User info
System.out.println ("Decrypting file, this may take a while.");
//First, we want the file in one array
String bigFile = "";
String finalString = "";
String temp = "";
String tempChar = "";
int itemp = 0;
int jtemp = 12;
File fi = new File (filePath);
FileReader fil = new FileReader (fi);
BufferedReader fin = new BufferedReader (fil);
for (int z = 0; z < getNumberOfLines (filePath); z++)
bigFile = bigFile + fin.readLine ();
fin.close ();
//The decrypting process
Loop1:
while (jtemp < bigFile.length ())//When there are no more code left to decrypt
{
temp = bigFile.substring (itemp, jtemp);
System.gc ();
for (int j = 0; j < theChars.length + 2; j++)
{
Loop2:
for (int l = 0; l < 100; l++)
{
if (temp.equals (key[j][l]))
{
if (j == theChars.length)
temp = temp.replace (temp, "[unsupported character]");
else if (j == theChars.length + 1)
temp = temp.replace (temp, "\n");
else
{
tempChar = theChars[j] + "";
temp = temp.replace (temp, tempChar);
}
finalString = finalString + temp + "";
itemp += 12;
jtemp += 12;
continue Loop1;
}
else
continue Loop2;
}
}
}
//Replace the codes that repsent |, $, § and ¥
finalString = finalString.replace ("[·vt]", "|").
replace ("[·dl]", "$").
replace ("[·es]", "§").
replace ("[·yy]", "¥");
//Finally write out the shit to a text file
File fil2 = new File (getOutputName (filePath, false));
FileWriter fw = new FileWriter (fil2);
BufferedWriter ffout = new BufferedWriter (fw);
ffout.write (finalString);
ffout.close ();
//User info
System.out.println ("Decrypting is done!");
}
private static int getNumberOfLines (String filePath) throws Exception //Goes thru a file and count the number of lines, and return the number.
{
File fi = new File (filePath);
FileReader fil = new FileReader (fi);
BufferedReader fout = new BufferedReader (fil);
String dummy = "";
int nrOfLines = 0;
while (dummy != null)
{
dummy = fout.readLine ();
nrOfLines++;
}
fil.close ();
fout.close ();
return nrOfLines - 1; // - 1 to avoid runtime error
}
private static String getOutputName (String filePath, boolean enorde) //enorde, Encrypt Or Decrypt
{ //Append extension kry or txt to the file. Also a check if there is no extension, if so, append .txt.
int place = filePath.lastIndexOf (".");
if (place != -1)
{
if (enorde)
filePath = filePath.substring (0, place + 1) + "kry";
else
filePath = filePath.substring (0, place + 1) + "txt";
}
else //If the retard user have no extension on his file
filePath = filePath + ".txt";
return filePath;
}
}