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