Skip to content

Instantly share code, notes, and snippets.

@tbenjis
Last active January 2, 2018 20:02
Show Gist options
  • Save tbenjis/9778361 to your computer and use it in GitHub Desktop.
Save tbenjis/9778361 to your computer and use it in GitHub Desktop.
Cryptographic statistical analysis for shift cipher encryption in java
/**
* @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