Mercurial > public > cpp-enigma
annotate enigma/rotor.cpp @ 0:74ebb2150658
Initial commit. Working on the rotor class.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Thu, 21 Jun 2012 21:05:26 -0500 |
parents | |
children | 1459e74fda3f |
rev | line source |
---|---|
bgneal@0 | 1 // Copyright (C) 2012 by Brian Neal. |
bgneal@0 | 2 // This file is part of Cpp-Enigma, the Enigma Machine simulation. |
bgneal@0 | 3 // Cpp-Enigma is released under the MIT License (see License.txt). |
bgneal@0 | 4 // |
bgneal@0 | 5 // rotor.cpp - Implementation file for the rotor class. |
bgneal@0 | 6 |
bgneal@0 | 7 #include <set> |
bgneal@0 | 8 #include <array> |
bgneal@0 | 9 #include <algorithm> |
bgneal@0 | 10 #include "rotor.h" |
bgneal@0 | 11 |
bgneal@0 | 12 using namespace enigma; |
bgneal@0 | 13 |
bgneal@0 | 14 namespace |
bgneal@0 | 15 { |
bgneal@0 | 16 const char* const ucase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
bgneal@0 | 17 const std::set<char> ucase_set(ucase, ucase + 26); |
bgneal@0 | 18 } |
bgneal@0 | 19 |
bgneal@0 | 20 rotor::rotor(const char* name, const char* wiring, int ring_setting, const char* stepping) |
bgneal@0 | 21 : rotor_name(name), |
bgneal@0 | 22 wiring_str(wiring), |
bgneal@0 | 23 ring_setting(ring_setting), |
bgneal@0 | 24 pos(0), |
bgneal@0 | 25 rotations(0) |
bgneal@0 | 26 { |
bgneal@0 | 27 // check wiring length |
bgneal@0 | 28 if (wiring_str.size() != 26) |
bgneal@0 | 29 { |
bgneal@0 | 30 throw rotor_error("invalid wiring length"); |
bgneal@0 | 31 } |
bgneal@0 | 32 |
bgneal@0 | 33 // ensure wiring contains only uppercase letters & every char must appear |
bgneal@0 | 34 // exactly once: |
bgneal@0 | 35 |
bgneal@0 | 36 std::array<int, 26> letter_counts {{ 0 }}; |
bgneal@0 | 37 for (int i = 0; i < 26; ++i) |
bgneal@0 | 38 { |
bgneal@0 | 39 const char c(wiring_str[i]); |
bgneal@0 | 40 |
bgneal@0 | 41 if (ucase_set.find(c) == ucase_set.end()) |
bgneal@0 | 42 { |
bgneal@0 | 43 throw rotor_error("invalid wiring"); |
bgneal@0 | 44 } |
bgneal@0 | 45 ++letter_counts[c - 'A']; |
bgneal@0 | 46 } |
bgneal@0 | 47 |
bgneal@0 | 48 if (std::find_if(letter_counts.begin(), |
bgneal@0 | 49 letter_counts.end(), |
bgneal@0 | 50 [](int n) { return n != 1; }) != letter_counts.end()) |
bgneal@0 | 51 { |
bgneal@0 | 52 throw rotor_error("invalid wiring; duplicate letter"); |
bgneal@0 | 53 } |
bgneal@0 | 54 } |