annotate enigma/tests/test_machine.t.h @ 4:2792ca4ffa84

Created enigma_machine class and tests.
author Brian Neal <bgneal@gmail.com>
date Sun, 24 Jun 2012 18:39:05 -0500
parents
children db1216d380b3
rev   line source
bgneal@4 1 // Copyright (C) 2012 by Brian Neal.
bgneal@4 2 // This file is part of Cpp-Enigma, the Enigma Machine simulation.
bgneal@4 3 // Cpp-Enigma is released under the MIT License (see License.txt).
bgneal@4 4 //
bgneal@4 5 // test_machine.t.h - Unit tests for the enigma_machine class.
bgneal@4 6
bgneal@4 7 #include <memory>
bgneal@4 8 #include <string>
bgneal@4 9 #include <vector>
bgneal@4 10 #include <cxxtest/TestSuite.h>
bgneal@4 11 #include "machine.h"
bgneal@4 12 #include "enigma_utils.h"
bgneal@4 13
bgneal@4 14 using namespace enigma;
bgneal@4 15
bgneal@4 16
bgneal@4 17 class stepping_test_suite : public CxxTest::TestSuite
bgneal@4 18 {
bgneal@4 19 public:
bgneal@4 20
bgneal@4 21 void test_double_stepping()
bgneal@4 22 {
bgneal@4 23 // Ensure the rotors step realistically by testing for a "double-step"
bgneal@4 24 // This example taken from
bgneal@4 25 // http://users.telenet.be/d.rijmenants/en/enigmatech.htm
bgneal@4 26 // in the section on "The Stepping Mechanism."
bgneal@4 27
bgneal@4 28 enigma_machine m({"III", "II", "I"}, {});
bgneal@4 29 m.set_display('K', 'D', 'O');
bgneal@4 30
bgneal@4 31 const std::vector<std::string> truth_data = {
bgneal@4 32 "KDP", "KDQ", "KER", "LFS", "LFT", "LFU",
bgneal@4 33 };
bgneal@4 34
bgneal@4 35 for (const auto& expected : truth_data)
bgneal@4 36 {
bgneal@4 37 m.key_press('A');
bgneal@4 38 TS_ASSERT_EQUALS(m.get_display(), expected);
bgneal@4 39 }
bgneal@4 40 }
bgneal@4 41 };
bgneal@4 42
bgneal@4 43
bgneal@4 44 class simple_cipher_test_suite : public CxxTest::TestSuite
bgneal@4 45 {
bgneal@4 46 public:
bgneal@4 47
bgneal@4 48 void setUp()
bgneal@4 49 {
bgneal@4 50 m.reset(new enigma_machine({"I", "II", "III"}, {}));
bgneal@4 51 m->set_display('A', 'A', 'A');
bgneal@4 52 plaintext = "AAAAA";
bgneal@4 53 ciphertext = "BDZGO";
bgneal@4 54 }
bgneal@4 55
bgneal@4 56 void test_simple_encrypt()
bgneal@4 57 {
bgneal@4 58 std::vector<char> buffer(plaintext.size());
bgneal@4 59 m->process_text(plaintext.c_str(), buffer.data(), plaintext.size());
bgneal@4 60 TS_ASSERT_EQUALS(ciphertext, std::string(buffer.begin(), buffer.end()));
bgneal@4 61 }
bgneal@4 62
bgneal@4 63 void test_simple_decrypt()
bgneal@4 64 {
bgneal@4 65 std::vector<char> buffer(plaintext.size());
bgneal@4 66 m->process_text(ciphertext.c_str(), buffer.data(), ciphertext.size());
bgneal@4 67 TS_ASSERT_EQUALS(plaintext, std::string(buffer.begin(), buffer.end()));
bgneal@4 68 }
bgneal@4 69
bgneal@4 70 private:
bgneal@4 71 std::unique_ptr<enigma_machine> m;
bgneal@4 72 std::string plaintext;
bgneal@4 73 std::string ciphertext;
bgneal@4 74 };
bgneal@4 75
bgneal@4 76
bgneal@4 77 // This example taken from Dirk Rijmenants' simulator manual.
bgneal@4 78 //
bgneal@4 79 // It is credited to Frode Weierud and Geoff Sullivan.
bgneal@4 80 // http://cryptocellar.com
bgneal@4 81 //
bgneal@4 82 class actual_decrypt_test_suite : public CxxTest::TestSuite
bgneal@4 83 {
bgneal@4 84 public:
bgneal@4 85 void setUp()
bgneal@4 86 {
bgneal@4 87 m.reset(new enigma_machine({"II", "IV", "V"}, {1, 20, 11}, "B",
bgneal@4 88 "AV BS CG DL FU HZ IN KM OW RX"));
bgneal@4 89 }
bgneal@4 90
bgneal@4 91 void decrypt(const std::string& start,
bgneal@4 92 const std::string& enc_key,
bgneal@4 93 const std::string& ciphertext,
bgneal@4 94 const std::string& truth_data)
bgneal@4 95 {
bgneal@4 96 // remove spaces & Kenngruppen from ciphertext
bgneal@4 97 std::string ctext(ciphertext.begin() + 5, ciphertext.end());
bgneal@4 98 ctext = remove_spaces(ctext);
bgneal@4 99
bgneal@4 100 // remove spaces from truth_data
bgneal@4 101 const std::string expected(remove_spaces(truth_data));
bgneal@4 102
bgneal@4 103 // decrypt message key to get start position
bgneal@4 104 m->set_display(start[0], start[1], start[2]);
bgneal@4 105 std::string key = m->process_text(enc_key);
bgneal@4 106
bgneal@4 107 // decrypt the message with the key
bgneal@4 108 m->set_display(key[0], key[1], key[2]);
bgneal@4 109
bgneal@4 110 const std::string plaintext = m->process_text(ctext);
bgneal@4 111
bgneal@4 112 TS_ASSERT_EQUALS(plaintext, expected);
bgneal@4 113 }
bgneal@4 114
bgneal@4 115 void test_decrpyt_1()
bgneal@4 116 {
bgneal@4 117 const std::string ciphertext =
bgneal@4 118 "RFUGZ EDPUD NRGYS ZRCXN"
bgneal@4 119 "UYTPO MRMBO FKTBZ REZKM"
bgneal@4 120 "LXLVE FGUEY SIOZV EQMIK"
bgneal@4 121 "UBPMM YLKLT TDEIS MDICA"
bgneal@4 122 "GYKUA CTCDO MOHWX MUUIA"
bgneal@4 123 "UBSTS LRNBZ SZWNR FXWFY"
bgneal@4 124 "SSXJZ VIJHI DISHP RKLKA"
bgneal@4 125 "YUPAD TXQSP INQMA TLPIF"
bgneal@4 126 "SVKDA SCTAC DPBOP VHJK";
bgneal@4 127
bgneal@4 128 const std::string truth_data =
bgneal@4 129 "AUFKL XABTE ILUNG XVONX"
bgneal@4 130 "KURTI NOWAX KURTI NOWAX"
bgneal@4 131 "NORDW ESTLX SEBEZ XSEBE"
bgneal@4 132 "ZXUAF FLIEG ERSTR ASZER"
bgneal@4 133 "IQTUN GXDUB ROWKI XDUBR"
bgneal@4 134 "OWKIX OPOTS CHKAX OPOTS"
bgneal@4 135 "CHKAX UMXEI NSAQT DREIN"
bgneal@4 136 "ULLXU HRANG ETRET ENXAN"
bgneal@4 137 "GRIFF XINFX RGTX";
bgneal@4 138
bgneal@4 139 decrypt("WXC", "KCH", ciphertext, truth_data);
bgneal@4 140 }
bgneal@4 141
bgneal@4 142 void test_decrpyt_2()
bgneal@4 143 {
bgneal@4 144 const std::string ciphertext =
bgneal@4 145 "FNJAU SFBWD NJUSE GQOBH"
bgneal@4 146 "KRTAR EEZMW KPPRB XOHDR"
bgneal@4 147 "OEQGB BGTQV PGVKB VVGBI"
bgneal@4 148 "MHUSZ YDAJQ IROAX SSSNR"
bgneal@4 149 "EHYGG RPISE ZBOVM QIEMM"
bgneal@4 150 "ZCYSG QDGRE RVBIL EKXYQ"
bgneal@4 151 "IRGIR QNRDN VRXCY YTNJR";
bgneal@4 152
bgneal@4 153 const std::string truth_data =
bgneal@4 154 "DREIG EHTLA NGSAM ABERS"
bgneal@4 155 "IQERV ORWAE RTSXE INSSI"
bgneal@4 156 "EBENN ULLSE QSXUH RXROE"
bgneal@4 157 "MXEIN SXINF RGTXD REIXA"
bgneal@4 158 "UFFLI EGERS TRASZ EMITA"
bgneal@4 159 "NFANG XEINS SEQSX KMXKM"
bgneal@4 160 "XOSTW XKAME NECXK";
bgneal@4 161
bgneal@4 162 decrypt("CRS", "YPJ", ciphertext, truth_data);
bgneal@4 163 }
bgneal@4 164
bgneal@4 165 private:
bgneal@4 166 std::unique_ptr<enigma_machine> m;
bgneal@4 167 };
bgneal@4 168
bgneal@4 169
bgneal@4 170 // This is the Kriegsmarine example from Dirk Rijmenants' simulator manual.
bgneal@4 171 //
bgneal@4 172 // It is credited to Stefan Krah and the M4 project:
bgneal@4 173 // http://www.bytereef.org/m4_project.html
bgneal@4 174 //
bgneal@4 175 class kriegsmarine_test_suite : public CxxTest::TestSuite
bgneal@4 176 {
bgneal@4 177 public:
bgneal@4 178
bgneal@4 179 void test_decrypt()
bgneal@4 180 {
bgneal@4 181 const std::string stecker = "1/20 2/12 4/6 7/10 8/13 14/23 15/16 17/25 18/26 22/24";
bgneal@4 182
bgneal@4 183 enigma_machine machine({"Beta", "II", "IV", "I"}, {0, 0, 0, 21}, "B-Thin", stecker);
bgneal@4 184
bgneal@4 185 std::string ciphertext = remove_spaces(
bgneal@4 186 "FCLC QRKN NCZW VUSX PNYM INHZ XMQX SFWX WLKJ AHSH NMCO CCAK UQPM KCSM"
bgneal@4 187 "HKSE INJU SBLK IOSX CKUB HMLL XCSJ USRR DVKO HULX WCCB GVLI YXEO AHXR"
bgneal@4 188 "HKKF VDRE WEZL XOBA FGYU JQUK GRTV UKAM EURB VEKS UHHV OYHA BCJW MAKL"
bgneal@4 189 "FKLM YFVN RIZR VVRT KOFD ANJM OLBG FFLE OPRG TFLV RHOW OPBE KVWM UQFM"
bgneal@4 190 "PWPA RMFH AGKX IIBG FCLC QRKM VA");
bgneal@4 191
bgneal@4 192 // remove the message indicators from the message (the first and last 2
bgneal@4 193 // groups of the message -- it appears the last partial group 'VA' should
bgneal@4 194 // be removed also)
bgneal@4 195
bgneal@4 196 ciphertext = std::string(ciphertext.begin() + 8, ciphertext.end() - 10);
bgneal@4 197
bgneal@4 198 machine.set_display('V', 'J', 'N', 'A');
bgneal@4 199 const std::string plaintext = machine.process_text(ciphertext);
bgneal@4 200
bgneal@4 201 const std::string truth_data = remove_spaces(
bgneal@4 202 "VONV ONJL OOKS JHFF TTTE"
bgneal@4 203 "INSE INSD REIZ WOYY QNNS"
bgneal@4 204 "NEUN INHA LTXX BEIA NGRI"
bgneal@4 205 "FFUN TERW ASSE RGED RUEC"
bgneal@4 206 "KTYW ABOS XLET ZTER GEGN"
bgneal@4 207 "ERST ANDN ULAC HTDR EINU"
bgneal@4 208 "LUHR MARQ UANT ONJO TANE"
bgneal@4 209 "UNAC HTSE YHSD REIY ZWOZ"
bgneal@4 210 "WONU LGRA DYAC HTSM YSTO"
bgneal@4 211 "SSEN ACHX EKNS VIER MBFA"
bgneal@4 212 "ELLT YNNN NNNO OOVI ERYS"
bgneal@4 213 "ICHT EINS NULL");
bgneal@4 214
bgneal@4 215 TS_ASSERT_EQUALS(plaintext, truth_data);
bgneal@4 216 }
bgneal@4 217
bgneal@4 218 };