1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
//! # ADFGX Cipher //! //! Implements the functionality for the ADFGX cipher. //! //! > The ADFGX cipher was a field cipher used by the German Army during World War I. It is closely //! related to the ADFGXC cipher (i.e. ADFGX is the predecessor to ADFGVX). //! //! > The cipher was a fractionating transposition cipher which combined a modified Polybius square //! with a single columnar transposition. //! //! > The cipher is named after the five possible letters used in the ciphertext: A, D, F, G and X. //! The letters were chosen deliberately because they are very different from one another in the //! Morse code. That reduced the possibility of operator error. use crate::{Cipher, CipherResult, ColumnarTransposition, PolybiusSquare}; /// An ADFGX cipher implementation. pub struct ADFGX { key: String, keyword: String, } impl ADFGX { /// Takes the key and keyword for the ADFGX cipher and returns a /// corresponding ADFGX struct. /// /// # Panics /// * If `key` is not 25 chars in length. /// * If `key` contains repeated chars. /// * If `key` is not valid ascii. /// * If `keyword` is not valid ascii. pub fn new(key: &str, keyword: &str) -> Self { assert_eq!(key.len(), 25, "`key` must be 25 chars in length"); Self { key: String::from(key), keyword: String::from(keyword), } } } impl Cipher for ADFGX { /// Enciphers the given plaintext (a str reference) using the ADFGX cipher /// and returns the ciphertext as a `CipherResult`. /// /// # Example /// ``` /// use ciphers::{Cipher, ADFGX}; /// /// let adfgx = ADFGX::new("PHQGMEAYNOFDXKRCVSZWBUTIL", "GERMAN"); /// /// let ctext = adfgx.encipher("DEFENDTHEEASTWALLOFTHECASTLE"); /// assert_eq!(ctext.unwrap(), "FFDGDDADXDAFAFXAAFAFDXDXXFDGDAGDDXXFAFADAFDXDDXDDADGXXGX"); /// ``` fn encipher(&self, ptext: &str) -> CipherResult { let ps = PolybiusSquare::new(&self.key, "ADFGX"); let ct = ColumnarTransposition::new(&self.keyword); ct.encipher(&ps.encipher(ptext)?) } /// Deciphers the given ciphertext (a str reference) using the ADFGX cipher /// and returns the plaintext as a `CipherResult`. /// /// # Example /// ``` /// use ciphers::{Cipher, ADFGX}; /// /// let adfgx = ADFGX::new("PHQGMEAYNOFDXKRCVSZWBUTIL", "GERMAN"); /// /// let ptext = adfgx.decipher("FFDGDDADXDAFAFXAAFAFDXDXXFDGDAGDDXXFAFADAFDXDDXDDADGXXGX"); /// assert_eq!(ptext.unwrap(), "DEFENDTHEEASTWALLOFTHECASTLE"); /// ``` fn decipher(&self, ctext: &str) -> CipherResult { let ps = PolybiusSquare::new(&self.key, "ADFGX"); let ct = ColumnarTransposition::new(&self.keyword); ps.decipher(&ct.decipher(ctext)?) } }