import java.util.Scanner; import java.io.File; import java.io.FileNotFoundException; public class Cipher { private double[] corpusFreqs = new double[26]; private double[] backupFreqs = {8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966, 0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074}; // Taken from Wikipedia public String encode(String input, int o) { String s = input.toLowerCase(); String crypt = ""; for (int i=0; i<s.length(); i++) { char l = s.charAt(i); if (Character.isLetter(l)) l = (char) ((l + o - (int)'a') % 26 + (int)'a'); crypt += l; } return crypt; } private void buildCorpusFreqs(String filename) { try { Scanner sc = new Scanner(new File(filename)); int totalCount = 0; while (sc.hasNext()) { String s = sc.nextLine(); String test = s.toLowerCase(); for (int i=0; i<test.length(); i++) { char c = test.charAt(i); if (Character.isLetter(c)) corpusFreqs[c-'a']++; totalCount++; } } sc.close(); for (int i=0; i<26; i++) { corpusFreqs[i] /= totalCount; } } catch (FileNotFoundException e) { System.out.println("Could not find " + filename + " to base decryption on!"); corpusFreqs = backupFreqs; } catch (Exception e) { System.out.println("Error " + e + " occurred... Using backup frequencies"); corpusFreqs = backupFreqs; } } public String decrypt(String s) { return decrypt(s, "Shakespeare.txt"); } public String decrypt(String s, String filename) { buildCorpusFreqs(filename); int testLength = s.length(); int[][] letters = new int[26][26]; for (int e=0; e<26; e++) { String test = encode(s, e); for (int l=0; l<test.length(); l++) { char c = test.charAt(l); if (Character.isLetter(c)) letters[e][c-'a']++; } } double biggestFreq = 0; int offset = 0; for (int e=0; e<26; e++) { double freqComp = 0; for (int i=0; i<26; i++) { freqComp += letters[e][i] * corpusFreqs[i]; } if (freqComp > biggestFreq) { biggestFreq = freqComp; offset = e; } } return encode(s, offset); } }