Last active
January 2, 2018 20:02
-
-
Save tbenjis/9778361 to your computer and use it in GitHub Desktop.
Cryptographic statistical analysis for shift cipher encryption in java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @tbenjis | |
* Cryptigraphic Statistical analysis | |
* Author: tunde | |
* | |
* */ | |
import java.awt.EventQueue; | |
import javax.swing.JFrame; | |
import javax.swing.JOptionPane; | |
import javax.swing.JPanel; | |
import javax.swing.JScrollPane; | |
import javax.swing.border.EmptyBorder; | |
import javax.swing.JTextPane; | |
import javax.swing.JLabel; | |
import java.awt.Font; | |
import java.awt.Color; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.ActionListener; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
import java.util.LinkedHashMap; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Map; | |
import javax.swing.JSeparator; | |
import javax.swing.JButton; | |
import java.awt.GridLayout; | |
public class StatisticalAnalysis extends JFrame implements ActionListener { | |
private JPanel contentPane; | |
private JLabel lblResults; | |
private JButton btnReplaceCharacter; | |
private JButton btnStart; | |
private JTextPane inputText; | |
private JTextPane outputText; | |
private JPanel panel; | |
private String values = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
private String cipher_keys = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
private String ciphertext; | |
private JPanel panel_cipher; | |
// the output | |
String output = ""; | |
/** | |
* Launch the application. | |
*/ | |
public static void main(String[] args) { | |
EventQueue.invokeLater(new Runnable() { | |
public void run() { | |
try { | |
StatisticalAnalysis frame = new StatisticalAnalysis(); | |
frame.setVisible(true); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
}); | |
} | |
/** | |
* Create the frame. | |
*/ | |
public StatisticalAnalysis() { | |
setResizable(false); | |
setTitle("Cryptanalysis"); | |
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
setBounds(100, 100, 869, 613); | |
contentPane = new JPanel(); | |
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); | |
setContentPane(contentPane); | |
contentPane.setLayout(null); | |
inputText = new JTextPane(); | |
inputText.setBounds(10, 35, 833, 147); | |
JScrollPane jsp1 = new JScrollPane(inputText); | |
jsp1.setBounds(10, 35, 833, 147); | |
contentPane.add(jsp1); | |
JLabel lblInput = new JLabel("Input:"); | |
lblInput.setForeground(Color.GRAY); | |
lblInput.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
lblInput.setBounds(10, 10, 451, 23); | |
contentPane.add(lblInput); | |
outputText = new JTextPane(); | |
outputText.setBounds(10, 364, 833, 152); | |
JScrollPane jsp = new JScrollPane(outputText); | |
jsp.setBounds(10, 364, 833, 152); | |
contentPane.add(jsp); | |
JLabel lblOutput = new JLabel("Output:"); | |
lblOutput.setForeground(Color.GRAY); | |
lblOutput.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
lblOutput.setBounds(10, 336, 566, 17); | |
contentPane.add(lblOutput); | |
JSeparator separator = new JSeparator(); | |
separator.setBounds(10, 256, 833, 14); | |
contentPane.add(separator); | |
JLabel lblStatistics = new JLabel("Statistics:"); | |
lblStatistics.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
lblStatistics.setForeground(Color.RED); | |
lblStatistics.setBounds(10, 214, 92, 14); | |
contentPane.add(lblStatistics); | |
JLabel lblChars = new JLabel("Chars:"); | |
lblChars.setForeground(Color.BLUE); | |
lblChars.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
lblChars.setBounds(10, 277, 64, 23); | |
contentPane.add(lblChars); | |
JLabel lblChiper = new JLabel("Key:"); | |
lblChiper.setForeground(Color.DARK_GRAY); | |
lblChiper.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
lblChiper.setBounds(10, 300, 64, 26); | |
contentPane.add(lblChiper); | |
btnReplaceCharacter = new JButton("Replace character"); | |
btnReplaceCharacter.setBounds(570, 541, 150, 23); | |
contentPane.add(btnReplaceCharacter); | |
btnStart = new JButton("START"); | |
btnStart.setFont(new Font("Tahoma", Font.BOLD, 11)); | |
btnStart.setForeground(new Color(0, 128, 0)); | |
btnStart.setBounds(754, 541, 89, 23); | |
contentPane.add(btnStart); | |
panel = new JPanel(); | |
panel.setBounds(110, 196, 733, 52); | |
contentPane.add(panel); | |
lblResults = new JLabel(""); | |
panel.add(lblResults); | |
lblResults.setFont(new Font("Courier New", Font.PLAIN, 13)); | |
panel_cipher = new JPanel(); | |
panel_cipher.setBounds(110, 273, 733, 52); | |
panel_cipher.setLayout(new GridLayout(2, cipher_keys.length(), 2, 2)); | |
contentPane.add(panel_cipher); | |
btnStart.addActionListener(this); | |
btnReplaceCharacter.addActionListener(this); | |
btnReplaceCharacter.setEnabled(false); | |
} | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
if (e.getSource() == btnStart) { | |
panel.removeAll(); | |
outputText.setText(""); | |
cipher_keys = values; | |
// get the frequency first | |
Map<Character, Integer> freq; | |
freq = countFreq(inputText.getText().toUpperCase()); | |
panel.setLayout(new GridLayout(2, freq.size(), 2, 2)); | |
// loop out all the data | |
for (Map.Entry<Character, Integer> key : freq.entrySet()) { | |
// get the lenght of the count | |
JLabel a = new JLabel(key.getKey().toString()); | |
panel.add(a); | |
} | |
// loop to show the count of characters | |
for (Map.Entry<Character, Integer> val : freq.entrySet()) { | |
// get the lenght of the count | |
JLabel b = new JLabel(val.getValue().toString()); | |
panel.add(b); | |
} | |
panel.revalidate(); | |
// clear the key values | |
panel_cipher.removeAll(); | |
// add the inital letters | |
for (int i = 0; i < values.length(); i++) { | |
// get the lenght of the count | |
JLabel b = new JLabel(String.valueOf(values.charAt(i))); | |
b.setForeground(Color.BLUE); | |
b.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
panel_cipher.add(b); | |
} | |
for (int i = 0; i < values.length(); i++) { | |
// get the lenght of the count | |
JLabel b = new JLabel(String.valueOf(values.charAt(i)) | |
.toLowerCase()); | |
b.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
panel_cipher.add(b); | |
} | |
panel_cipher.revalidate(); | |
// add the ciphertext to the string | |
ciphertext = inputText.getText().toUpperCase(); | |
btnReplaceCharacter.setEnabled(true); | |
} | |
if (e.getSource() == btnReplaceCharacter) { | |
panel_cipher.removeAll(); | |
// add the inital letters | |
for (int i = 0; i < values.length(); i++) { | |
// get the lenght of the count | |
JLabel b = new JLabel(String.valueOf(values.charAt(i))); | |
b.setForeground(Color.BLUE); | |
b.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
panel_cipher.add(b); | |
} | |
boolean fromOK = false; | |
boolean toOK = false; | |
String fromString = ""; | |
// get the strings and convert to upper case | |
while (!fromOK) { | |
fromString = JOptionPane | |
.showInputDialog("What letter(s) do you want to replace?"); | |
if (fromString.matches("[a-zA-Z]+")) { | |
fromOK = true; | |
fromString = fromString.toUpperCase().replaceAll( | |
"(.)(?=.*\\1)", ""); | |
} else { | |
JOptionPane.showMessageDialog(this, "Enter letters only"); | |
} | |
} | |
String toString = ""; | |
while (!toOK) { | |
toString = JOptionPane | |
.showInputDialog("What are you replacing it with?"); | |
if (toString.matches("[a-zA-Z]+")) { | |
toOK = true; | |
toString = toString.toUpperCase().replaceAll( | |
"(.)(?=.*\\1)", ""); | |
} else { | |
JOptionPane.showMessageDialog(this, "Enter letters only"); | |
} | |
} | |
// loop to replace each char | |
String old_str; | |
String rep_str; | |
for (int i = 0; i < toString.length(); i++) { | |
try { | |
rep_str = String.valueOf(toString.charAt(i)).toUpperCase(); | |
old_str = String.valueOf(fromString.charAt(i)).toUpperCase(); | |
//replace only upper case strings | |
ciphertext = ciphertext.replaceAll("(?u)" + old_str, | |
rep_str.toLowerCase()); | |
cipher_keys = cipher_keys.replaceAll(old_str, | |
rep_str.toLowerCase()); | |
} catch (Exception ex) { | |
JOptionPane.showMessageDialog(this, | |
"Please check your replacement / original values"); | |
// exit the loop | |
return; | |
} | |
} | |
// set the new chipher text | |
for (int i = 0; i < cipher_keys.length(); i++) { | |
// get the lenght of the count | |
JLabel b = new JLabel(String.valueOf(cipher_keys.charAt(i)) | |
.toLowerCase()); | |
b.setFont(new Font("Tahoma", Font.BOLD, 14)); | |
panel_cipher.add(b); | |
} | |
// print out the output | |
output += "The character(s): \"" + fromString | |
+ "\" is replaced with \"" + toString + "\"\n\n" | |
+ ciphertext + "\n\n"; | |
this.outputText.setText(output); | |
// cleanup | |
panel_cipher.revalidate(); | |
} | |
} | |
/** | |
* Get the frequency of a character | |
* | |
* @param s | |
* @return | |
*/ | |
private Map<Character, Integer> countFreq(String s) { | |
Map<Character, Integer> map = new HashMap<Character, Integer>(); | |
for (int i = 0; i < s.length(); i++) { | |
char c = s.charAt(i); | |
// escape special chars | |
if (!Character.isLetter(c)) { | |
continue; | |
} | |
Integer val = map.get(new Character(c)); | |
if (val != null) { | |
map.put(c, new Integer(val + 1)); | |
} else { | |
map.put(c, 1); | |
} | |
} | |
char charEnc; | |
// find if the map has any other alphabet | |
for (int i = 0; i < values.length(); i++) { | |
charEnc = values.charAt(i); | |
if (map.containsKey(charEnc) == false) { | |
map.put(charEnc, 0); | |
} | |
} | |
return sortByComparator(map); | |
} | |
/** | |
* Sort the values thats why we use this since treemap sorts only the keys. | |
* returns the entries in sorted order | |
* | |
* @param map | |
* @return | |
*/ | |
private static Map<Character, Integer> sortByComparator( | |
Map<Character, Integer> unsortMap) { | |
List list = new LinkedList(unsortMap.entrySet()); | |
// sort list based on comparator | |
Collections.sort(list, new Comparator() { | |
public int compare(Object o1, Object o2) { | |
// we flip o2 - o1 to sort in descending order | |
return ((Comparable) ((Map.Entry) (o2)).getValue()) | |
.compareTo(((Map.Entry) (o1)).getValue()); | |
} | |
}); | |
// put sorted list into map again | |
// LinkedHashMap make sure order in which keys were inserted | |
Map sortedMap = new LinkedHashMap<Character, Integer>(); | |
for (Iterator it = list.iterator(); it.hasNext();) { | |
Map.Entry entry = (Map.Entry) it.next(); | |
sortedMap.put(entry.getKey(), entry.getValue()); | |
} | |
return sortedMap; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment