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 (2012-06-22) |
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 }
|