Mercurial > public > cpp-enigma
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/enigma/tests/test_machine.t.h Sun Jun 24 18:39:05 2012 -0500 @@ -0,0 +1,218 @@ +// Copyright (C) 2012 by Brian Neal. +// This file is part of Cpp-Enigma, the Enigma Machine simulation. +// Cpp-Enigma is released under the MIT License (see License.txt). +// +// test_machine.t.h - Unit tests for the enigma_machine class. + +#include <memory> +#include <string> +#include <vector> +#include <cxxtest/TestSuite.h> +#include "machine.h" +#include "enigma_utils.h" + +using namespace enigma; + + +class stepping_test_suite : public CxxTest::TestSuite +{ +public: + + void test_double_stepping() + { + // Ensure the rotors step realistically by testing for a "double-step" + // This example taken from + // http://users.telenet.be/d.rijmenants/en/enigmatech.htm + // in the section on "The Stepping Mechanism." + + enigma_machine m({"III", "II", "I"}, {}); + m.set_display('K', 'D', 'O'); + + const std::vector<std::string> truth_data = { + "KDP", "KDQ", "KER", "LFS", "LFT", "LFU", + }; + + for (const auto& expected : truth_data) + { + m.key_press('A'); + TS_ASSERT_EQUALS(m.get_display(), expected); + } + } +}; + + +class simple_cipher_test_suite : public CxxTest::TestSuite +{ +public: + + void setUp() + { + m.reset(new enigma_machine({"I", "II", "III"}, {})); + m->set_display('A', 'A', 'A'); + plaintext = "AAAAA"; + ciphertext = "BDZGO"; + } + + void test_simple_encrypt() + { + std::vector<char> buffer(plaintext.size()); + m->process_text(plaintext.c_str(), buffer.data(), plaintext.size()); + TS_ASSERT_EQUALS(ciphertext, std::string(buffer.begin(), buffer.end())); + } + + void test_simple_decrypt() + { + std::vector<char> buffer(plaintext.size()); + m->process_text(ciphertext.c_str(), buffer.data(), ciphertext.size()); + TS_ASSERT_EQUALS(plaintext, std::string(buffer.begin(), buffer.end())); + } + +private: + std::unique_ptr<enigma_machine> m; + std::string plaintext; + std::string ciphertext; +}; + + +// This example taken from Dirk Rijmenants' simulator manual. +// +// It is credited to Frode Weierud and Geoff Sullivan. +// http://cryptocellar.com +// +class actual_decrypt_test_suite : public CxxTest::TestSuite +{ +public: + void setUp() + { + m.reset(new enigma_machine({"II", "IV", "V"}, {1, 20, 11}, "B", + "AV BS CG DL FU HZ IN KM OW RX")); + } + + void decrypt(const std::string& start, + const std::string& enc_key, + const std::string& ciphertext, + const std::string& truth_data) + { + // remove spaces & Kenngruppen from ciphertext + std::string ctext(ciphertext.begin() + 5, ciphertext.end()); + ctext = remove_spaces(ctext); + + // remove spaces from truth_data + const std::string expected(remove_spaces(truth_data)); + + // decrypt message key to get start position + m->set_display(start[0], start[1], start[2]); + std::string key = m->process_text(enc_key); + + // decrypt the message with the key + m->set_display(key[0], key[1], key[2]); + + const std::string plaintext = m->process_text(ctext); + + TS_ASSERT_EQUALS(plaintext, expected); + } + + void test_decrpyt_1() + { + const std::string ciphertext = + "RFUGZ EDPUD NRGYS ZRCXN" + "UYTPO MRMBO FKTBZ REZKM" + "LXLVE FGUEY SIOZV EQMIK" + "UBPMM YLKLT TDEIS MDICA" + "GYKUA CTCDO MOHWX MUUIA" + "UBSTS LRNBZ SZWNR FXWFY" + "SSXJZ VIJHI DISHP RKLKA" + "YUPAD TXQSP INQMA TLPIF" + "SVKDA SCTAC DPBOP VHJK"; + + const std::string truth_data = + "AUFKL XABTE ILUNG XVONX" + "KURTI NOWAX KURTI NOWAX" + "NORDW ESTLX SEBEZ XSEBE" + "ZXUAF FLIEG ERSTR ASZER" + "IQTUN GXDUB ROWKI XDUBR" + "OWKIX OPOTS CHKAX OPOTS" + "CHKAX UMXEI NSAQT DREIN" + "ULLXU HRANG ETRET ENXAN" + "GRIFF XINFX RGTX"; + + decrypt("WXC", "KCH", ciphertext, truth_data); + } + + void test_decrpyt_2() + { + const std::string ciphertext = + "FNJAU SFBWD NJUSE GQOBH" + "KRTAR EEZMW KPPRB XOHDR" + "OEQGB BGTQV PGVKB VVGBI" + "MHUSZ YDAJQ IROAX SSSNR" + "EHYGG RPISE ZBOVM QIEMM" + "ZCYSG QDGRE RVBIL EKXYQ" + "IRGIR QNRDN VRXCY YTNJR"; + + const std::string truth_data = + "DREIG EHTLA NGSAM ABERS" + "IQERV ORWAE RTSXE INSSI" + "EBENN ULLSE QSXUH RXROE" + "MXEIN SXINF RGTXD REIXA" + "UFFLI EGERS TRASZ EMITA" + "NFANG XEINS SEQSX KMXKM" + "XOSTW XKAME NECXK"; + + decrypt("CRS", "YPJ", ciphertext, truth_data); + } + +private: + std::unique_ptr<enigma_machine> m; +}; + + +// This is the Kriegsmarine example from Dirk Rijmenants' simulator manual. +// +// It is credited to Stefan Krah and the M4 project: +// http://www.bytereef.org/m4_project.html +// +class kriegsmarine_test_suite : public CxxTest::TestSuite +{ +public: + + void test_decrypt() + { + const std::string stecker = "1/20 2/12 4/6 7/10 8/13 14/23 15/16 17/25 18/26 22/24"; + + enigma_machine machine({"Beta", "II", "IV", "I"}, {0, 0, 0, 21}, "B-Thin", stecker); + + std::string ciphertext = remove_spaces( + "FCLC QRKN NCZW VUSX PNYM INHZ XMQX SFWX WLKJ AHSH NMCO CCAK UQPM KCSM" + "HKSE INJU SBLK IOSX CKUB HMLL XCSJ USRR DVKO HULX WCCB GVLI YXEO AHXR" + "HKKF VDRE WEZL XOBA FGYU JQUK GRTV UKAM EURB VEKS UHHV OYHA BCJW MAKL" + "FKLM YFVN RIZR VVRT KOFD ANJM OLBG FFLE OPRG TFLV RHOW OPBE KVWM UQFM" + "PWPA RMFH AGKX IIBG FCLC QRKM VA"); + + // remove the message indicators from the message (the first and last 2 + // groups of the message -- it appears the last partial group 'VA' should + // be removed also) + + ciphertext = std::string(ciphertext.begin() + 8, ciphertext.end() - 10); + + machine.set_display('V', 'J', 'N', 'A'); + const std::string plaintext = machine.process_text(ciphertext); + + const std::string truth_data = remove_spaces( + "VONV ONJL OOKS JHFF TTTE" + "INSE INSD REIZ WOYY QNNS" + "NEUN INHA LTXX BEIA NGRI" + "FFUN TERW ASSE RGED RUEC" + "KTYW ABOS XLET ZTER GEGN" + "ERST ANDN ULAC HTDR EINU" + "LUHR MARQ UANT ONJO TANE" + "UNAC HTSE YHSD REIY ZWOZ" + "WONU LGRA DYAC HTSM YSTO" + "SSEN ACHX EKNS VIER MBFA" + "ELLT YNNN NNNO OOVI ERYS" + "ICHT EINS NULL"); + + TS_ASSERT_EQUALS(plaintext, truth_data); + } + +};