I wrote a XOR encryption algorithm that ended up taking up a lot of code. It works (I tested it with Project Euler problem 59) and encrypts/decrypts accurately. It encrypts character in UTF-8 to keep the program simple. However, I don't know how much of the code I wrote is need and not already available some other java class.
package algorithms; public class Encryptor { int length = 0; /** * XOR encryptor */ public Encryptor(){} /** * @param message - the message to be encrypted * @param key - password for encryption * @return the encrypted message */ public String encrypt(String message, String key) { String enc = "";//String that will contain the encrypted message length = message.length();//length of the message String[] mess = toArray(message);//Binary values of every character in the message String[] key1 = makeKey(toArray(key));//Binary values of the characters in the key repeated to the required length if needed for(int i = 0; i < length; i++)//loop to add each encrypted character to enc { enc+=String.valueOf((char)binaryTobyte(binaryAdd(mess[i], key1[i]))); } return enc;//encrypted message } /** * @param str - String to be made into a String[] of binary values * @return - String[] of the binary representatino of every letter in String str */ private String[] toArray(String str) { String[] bin = new String[str.length()];//array that will conatin the binary values of every character in str byte[] vals = str.getBytes();//the byte vales of the message, synonymous the the char value of each letter for(int i = 0; i < bin.length; i++)//loop adding the binary translation of every letter to the bin array { bin[i] = toBinary(vals[i]); } return bin; } /** * @param arr - Binary String[] of the key * @return - Returns the Binary key, the array returned represents the letters in the key, translated to binary, and then repeated to the length of the message to be encrypted * Should be ran after the toArray method with the array from that method. */ private String[] makeKey(String[] arr) { String[] key = new String[length];//String[] that will contain the repeated, if necessary, binary values for each character in the key int ind = 0;//indexes arr for(int i = 0; i < length; i++)//loop to fill key[] { if(ind >= arr.length)//resets ind if greater than the number of values in arr { ind = 0; } key[i] = arr[ind]; ind++; } return key; } /** * @param bin1 - String containing a binary value * @param bin2 - String containing another binary value; * @return an array of the combined binary String values * @throws Throws an exception if either String is not binary. */ private byte[] binaryAdd(String bin1, String bin2) { byte[] sum;//array that will contain the combined bin1 and bin2 if(bin1.contains("2")||bin1.contains("3")||bin1.contains("4")||bin1.contains("5")||bin1.contains("6")||bin1.contains("7")||bin1.contains("8")||bin1.contains("9")) { throw new IllegalArgumentException("Argument not binary."); } if(bin2.contains("2")||bin2.contains("3")||bin2.contains("4")||bin2.contains("5")||bin2.contains("6")||bin2.contains("7")||bin2.contains("8")||bin2.contains("9")) { throw new IllegalArgumentException("Argument not binary."); } if(bin1.length()>=bin2.length())//makes the array equal to the longest String of binary values { sum = new byte[bin1.length()]; } else { sum = new byte[bin2.length()]; } for(int i = 0; i < sum.length; i++)//combines each bit and adds it to the sum array { byte a = Byte.parseByte(bin1.substring(i, i+1)); byte b = Byte.parseByte(bin2.substring(i, i+1)); if(a == b)// 0 -> 0 = 0 & 1 -> 1 = 0 in binary { sum[i]=0; } else// 1 -> 0 = 1 & 0 -> 1 = 1 in binary { sum[i]=1; } } return sum; } /** * @param num - byte value to be converted to an int value * @return The absolute value of the byte value 'num' */ private int toInt(byte num) { return Math.abs(Integer.parseInt(Byte.toString(num)));//question here: When testing Byte.toString(), I found that the value 128 when put into that method, Byte.toString(), returns as -128 and messed up the values. Why does Byte.toString((byte) 128) = "-128"? } /** * @param num - byte value to be made binary * @return String containing the binary translation of value num, length % 8 always equals 0. */ private String toBinary(byte num) { String bin = Integer.toBinaryString(toInt(num));//takes num and makes it inter an integer and then into a Binary String. while(bin.length()%8!=0)//if the length is not 8, 16, 24, 32, etc... evenly divisible by eight, adds 0's to the front { bin = "0".concat(bin); } return bin; } /** * @param bin - binary byte[] to be translated the a non-binary number * @return the byte value of bin */ private byte binaryTobyte(byte[] bin) { byte num = 0;//variable that will contain the 8-bit translation of the argument array int exp = bin.length-1;//starts at the length of the array - 1 because the first value in a binary number is 2^0. If you are confused, look it up. for(int i = 0; i < bin.length; i++)//loop to add values of the 1's to num. { if(bin[i]==1) { num+=Math.pow(2, exp); } exp--; } return num; } public static void main(String[] args) {} }
The program runs perfectly, I haven't benchmarked it to see how fast it is able to encrypt, but I know it's accurate. This program is not optimized, so optimizations are welcome.