import java.io.*; import java.util.*; public class Cipher{ private double[] CorpusFreqs; private int count; private void buildCorpusFreq(String filename){ CorpusFreqs = new double[26]; count = 0; try { Scanner sc = new Scanner (new File(filename)); while (sc.hasNext()) { String s = sc.nextLine(); s=s.toLowerCase(); for (int i=0;i<s.length();i++) { char c = s.charAt(i); if (c >= 'a' && c<='z'){ int val = c - 'a'; CorpusFreqs[val]++; count++; } } } } catch (Exception e) {} for (int i=0;i<26;i++) { CorpusFreqs[i] = CorpusFreqs[i]/count; } } public String rot(String s, int n){ String ans = ""; int place = 0; for (int i = 0; i < s.length(); i ++){ place = s.charAt(i); if ((place >= 'A') && (place <= 'Z')){ place = place + n; if (place > 'Z'){ place = place - 26; } if (place < 'A'){ place = place + 26; } } else if ((place >= 'a') && (place <= 'z')){ place = place + n; if (place > 'z'){ place = place - 26; } if (place < 'a'){ place = place + 26; } } ans = ans + String.valueOf((char)place); } return ans; } public double similar(String message) { double[] Freqs = new double[26]; String s = message; s=s.toLowerCase(); int count = 0; for (int i=0;i<s.length();i++) { char c = s.charAt(i); if (c >= 'a' && c<='z'){ int val = c - 'a'; Freqs[val]++; count++; } } for (int i=0;i<26;i++) { Freqs[i] = Freqs[i]/count; } double dist = 0.0; for (int i=0;i<26;i++) { dist = dist + Math.pow((Freqs[i] - CorpusFreqs[i]), 2); } dist = Math.sqrt(dist); return dist; } public String decode (String message) { String result = ""; double mindist = 100000.0; int offset = 0; for (int i=0;i<26;i++) { String s = this.rot(message, i); if (similar(s) < mindist) { mindist = similar(s); offset = i; } } result = this.rot(message, offset); return result; } public String toString(){ return Arrays.toString(CorpusFreqs); } public static void main (String args[]){ Cipher c = new Cipher(); c.buildCorpusFreq("Dracula.txt"); String s = c.rot("Shawn jon bong thongs like king kong", 5); System.out.println(c.decode(s)); } }