From 5031cf3498cdca14319b79229296aca188b47a37 Mon Sep 17 00:00:00 2001 From: magnasilvar <3359919+magnasilvar@users.noreply.github.com> Date: Sat, 21 Mar 2020 19:46:30 +0100 Subject: [PATCH] Add vigenere cipher (decryption part) Coded during the 2015 Parrot "hack mon annonce" event. --- README.md | 27 +++++++++++++++- Vigenere.java | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 Vigenere.java diff --git a/README.md b/README.md index 23c90d5..ecceaa6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,27 @@ # vigenere-cipher -Java version of the Vigenère cipher (created in 1553), now breakable (since 1863) + +Java implementation of the **Vigenère cipher** (decryption part) as part of the "_hack mon annonce_" event organized by [Parrot](https://github.com/Parrot-Developers) in **2015**. + +## Setup + +* Java: `Oracle JDK 1.8` + +## How to + +At the root level of the project : +* Compile Vigenere java class with the `javac` command. +* Run the compiled class with the `java` command and the following arguments (respecting this order): + 1. Decryption key (Hexadecimal format needed ! It was the key's format provided during the event), + 2. Alphabet to use, + 3. Encrypted words (with Vigenère cipher). + +> Powershell example: +```powershell +PS C:\GIT\vigenere-cipher> javac .\Vigenere.java +PS C:\vigenere-cipher> java Vigenere 434c45 ABCDEFGHIJKLMNOPQRSTUVWXYZ JPPNZ +Clé: CLE +Alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ +Message clair: HELLO +``` + +> CAUTION - Use the same case for your 3 arguments ! diff --git a/Vigenere.java b/Vigenere.java new file mode 100644 index 0000000..f3dac91 --- /dev/null +++ b/Vigenere.java @@ -0,0 +1,87 @@ +import javax.xml.bind.DatatypeConverter; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Classe permettant de déchiffrer un message codé par le chiffrement de Vigenère + */ +public class Vigenere { + + public static void main(final String[] args) { + if (args != null && args.length == 3) { + final String key = hexaToString(args[0]); + final String alphabet = args[1]; + final String cryptedMsg = args[2]; + final String repeatedKey = generateRepeatedKey(key, cryptedMsg.length()); + System.out.println("Cl\u00e9: " + key); + System.out.println("Alphabet: " + alphabet); + System.out.println("Message clair: " + vigenereDecrypt(repeatedKey, alphabet, cryptedMsg)); + } else { + System.out.println("Bad use ! Syntax : \"key\" \"alphabet\" \"encrypted sequence\""); + } + } + + /** + * Convertit une chaine hexadécimal en chaine de caractères + * + * @param hexaString Chaine hexadécimal + * @return Chaine de caractère + */ + public static String hexaToString(final String hexaString) { + return new String(DatatypeConverter.parseHexBinary(hexaString)); + } + + /** + * Génère la clé répétée + * + * @param key Clé + * @param msgLength Taille du message codé + * @return La clé répétée + */ + public static String generateRepeatedKey(final String key, final int msgLength) { + final StringBuilder repeatedKey = new StringBuilder(); + while (repeatedKey.length() < msgLength) { + repeatedKey.append(key); + } + repeatedKey.setLength(msgLength); + return repeatedKey.toString(); + } + + /** + * Décrypte un message codé avec le chiffrement de Vigenère + * + * @param repeatedKey Clé répété + * @param alphabet Alphabet pour le décryptage + * @param cryptedMsg Message encrypté + * @return Message décrypté + */ + public static String vigenereDecrypt(final String repeatedKey, final String alphabet, final String cryptedMsg) { + final StringBuilder result = new StringBuilder(); + Map> square = new HashMap>(); + final int nbAlphaEl = alphabet.length(); + // Construction du carré de Vigenère + for (int i = 0; i < nbAlphaEl; i++) { + // On ne récupère que les colonnes qui nous intéressent, à savoir celles de la clé + if (repeatedKey.contains(String.valueOf(alphabet.charAt(i)))) { + final Map column = new HashMap<>(); + for (int j = 0; j < nbAlphaEl; j++) { + column.put(alphabet.charAt(j), alphabet.charAt((j + i) % nbAlphaEl)); + } + square.put(alphabet.charAt(i), column); + } + } + // Décryptage + for (int i = 0; i < cryptedMsg.length(); i++) { + Set lines = square.get(repeatedKey.charAt(i)).keySet(); + for (final Character line : lines) { + if (square.get(repeatedKey.charAt(i)).get(line) == cryptedMsg.charAt(i)) { + result.append(line); + break; + } + } + } + return result.toString(); + } + +}