Mercurial > public > cpp-enigma
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 }; |