public class Lab05Thread extends Thread { private static final String eKey = "foobarbaz"; private static final String dKey = "aoq.geasl"; public static void main(String[] args) { /* Converts the encryption key into a matrix */ int[][] eMatrix = keyToMatrix(eKey); /* Converts the decryption key into a matrix */ int[][] dMatrix = keyToMatrix(dKey); /* Our plaintext to be encrypted */ String text = "hello, test."; String cipher = transform(eMatrix, text, 2); /* The below should be "nuvfxprhkjn " */ System.out.println("\"" + cipher + "\""); /* The below should be "hello, test." */ System.out.println("\"" + transform(dMatrix, cipher, 2) + "\""); } /** * Performs a matrix by vector multiplication. * * @param matrix The matrix being multiplied * @param vector The vector to multiply by */ public static int[] multiply(int[][] matrix, int[] vector) { int[] encVector = new int[vector.length]; for (int i = 0; i < matrix.length; i++) { encVector[i] = 0; for (int j = 0; j < matrix[i].length; j++) { encVector[i] += matrix[i][j] * vector[j]; } encVector[i] %= 29; } return encVector; } /** * Converts a character into its integer equivalent for the Hill cipher. *
* This means a = 1; b = 2; c = 3; ... ; z = 25; SPACE=26, .=27, COMMA=28. * * @param c The character which is being converted. */ public static int charToNumber(char c) { switch (c) { case ' ': return 26; case '.': return 27; case ',': return 28; default: return c - 'a'; } } /** * Converts text to an array. The text must consist only of lowercase * letters. The conversion is a=0, b=1, c=2, etc. * * @param text The text; must consist only of lowercase letters. */ public static int[] stringToArray(String text) { int[] vector = new int[text.length()]; for (int i = 0; i < vector.length; i++) { char c = text.charAt(i); vector[i] = charToNumber(c); } return vector; } /** * Converts an array given from stringToArray back to a String. * * @param array The array to convert. */ public static String arrayToString(int[] array) { StringBuffer r = new StringBuffer(array.length); for (int i = 0; i < array.length; i++) { char c = (char)array[i]; switch (c) { case 26: r.append(' '); break; case 27: r.append('.'); break; case 28: r.append(','); break; default: r.append((char)(array[i] + 'a')); } } return r.toString(); } /** * Encrypts some text with the Hill cipher. The text must consist of only * lowercase letters and must be a multiple of the length of the key matrix. * The encryption encrypts the text in blocks and returns the concatenation * of the results. * * @param key The key matrix. Must be be of dimensions N by N. * @param text The text to encrypt. Must be of length k*N, k is an integer. * @param numThreads The number of threads to use. Assumes each thread gets * at least one block. */ public static String transform(int[][] key, String text, int numThreads) { int blocks = text.length() / key.length; int size = key.length; StringBuffer result = new StringBuffer(text.length()); for (int i = 0; i < blocks; i++) { int[] block = stringToArray(text.substring(size*i, size*i + size)); result.append(arrayToString(multiply(key, block))); } return result.toString(); } /** * Transforms a text key to a matrix key. The text key must consist only of * lowercase letters. The conversion is a=0, b=1, c=2, etc. * * @param key The text key; must consist only of lowercase letters. */ public static int[][] keyToMatrix(String key) { int length = (int)Math.sqrt(key.length()); int[][] matrix = new int[length][length]; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix.length; j++) { char c = key.charAt(i*3 + j); matrix[i][j] = charToNumber(c); } } return matrix; } }