import java.io.*; import java.util.*; public class Cipher { private double[] CorpusFreqs; public Cipher() { CorpusFreqs = new double[26]; buildCorpusFreq("Anna_Karenina.txt"); } public String encode(String str, int offset) { String ans = ""; String s = str.toLowerCase(); if (offset < 0) offset = offset + 26; for (int i=0; i<s.length(); i++) { ans += rotate(s.charAt(i), offset); } return ans; } public char rotate(char c, int offset) { if (c >= 97 && c <= 122) c = (char) ((int)c + offset); if (c > 122) c = (char) ((int)c - 26); return c; } private void buildCorpusFreq(String filename) { try { Scanner scan = new Scanner(new File(filename)); int total = 0; while (scan.hasNext()) { String s = scan.nextLine(); s = s.toLowerCase(); for (int i=0; i<s.length(); i++) { char c = s.charAt(i); total++; if (c >= 97 && c <= 122) CorpusFreqs[c-97]++; } } for (int i=0; i<CorpusFreqs.length; i++) CorpusFreqs[i] = CorpusFreqs[i] / total; } catch (Exception e) {} } public double[] getCorpusFreqs() { return CorpusFreqs; } public void printCorpusFreqs() { for (int i=0; i<CorpusFreqs.length; i++) System.out.println((char) (i+97) + ": " + CorpusFreqs[i]); } public double[] getFrequency(String s) { double[] freq = new double[26]; int total = 0; for (int i=0; i<s.length(); i++) { char c = s.charAt(i); total++; if (c >= 97 && c <= 122) freq[c-97]++; } for (int i=0; i<freq.length; i++) freq[i] = freq[i] / total; return freq; } public double getDifference(String rotated) { //Assumes encoded is lowercase double[] freq = getFrequency(rotated); double diff = 0; for (int i=0; i<freq.length; i++) diff += Math.abs(freq[i] - CorpusFreqs[i]); return diff; } public int decode(String encoded) { double min = getDifference(encoded); int ans = 0; double nextDiff; for (int i=1; i<26; i++) { nextDiff = getDifference(encode(encoded, i)); if (min > nextDiff) { min = nextDiff; ans = i; } } return ans; } public static void main(String[] args) { Cipher c = new Cipher(); c.printCorpusFreqs(); String x = c.encode("I really like to eat pizza", 10); System.out.println(c.decode(x)); System.out.println(c.encode(x, c.decode(x))); } }