summaryrefslogtreecommitdiffstats
path: root/src/crypt/cryptclasscaesar.cpp
blob: 87bf999fede884dd84704e9cca79d7f17f52f62d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "cryptclasscaesar.h"

const int CryptClassCaesar::LOWERBOUND = 'A';
const int CryptClassCaesar::UPPERBOUND = 'Z';

/**
 * @brief CryptClassCaesar::CryptClassCaesar constructor for caesar encryption
 */
CryptClassCaesar::CryptClassCaesar()
    :CryptClassBase()
{
    qDebug("CryptClassCaesar::CryptClassCaesar()");
}

/**
 * @brief CryptClassCaesar::~CryptClassCaesar destructor for caesar encryption
 */
CryptClassCaesar::~CryptClassCaesar()
{
    qDebug("CryptClassCaesar::~CryptClassCaesar()");
}

/**
 * @brief CryptClassCaesar::encrypt encrypt the PlainText with the specific rotation
 */
void CryptClassCaesar::encrypt()
{
    qDebug() << "CryptClassCaesar::encrypt()";

    buildMap();
    // convert into upper letters
    m_clearText = m_clearText.toUpper();
    // clear cryptText
    m_cryptText.clear();
    // Set offset into 0
    mapOffset = 0;
    // Space counter
    int spaceCount = 0;

    for (int i = 0; i < m_clearText.size(); i++)
    {
        // only accept letters between 'A' and 'Z'
        if (m_clearText[i] >= (char) LOWERBOUND && m_clearText[i] <= (char) UPPERBOUND)
        {
            // encrypt Letters and rotate roter
            m_cryptText.append(substitutionsMap[LOWERBOUND + (((m_clearText[i] - LOWERBOUND)
                                                + mapOffset++) % (26))]);

            // insert spaces
            if (!(++spaceCount % 5))
            {
                m_cryptText.append(" ");
            }
        }
    }
}

/**
 * @brief CryptClassCaesar::decrypt encrypt the PlainText with the specific rotation
 */
void CryptClassCaesar::decrypt()
{
    qDebug("CryptClassCaesar::decrypt()");

    buildMap();
    int tmp = 0;

    m_cryptText = m_cryptText.toUpper();
    // delete clear text
    m_clearText.clear();
    // set offset into 0
    mapOffset = 0;

    for (int i = 0; i < m_cryptText.size(); i++)
    {
        // only accept letters between 'A' and 'Z'
        if (m_cryptText[i] >= (char) LOWERBOUND && m_cryptText[i] <= (char) UPPERBOUND)
        {
            // decrypt letters and rotate rotor backwards
            tmp = ((substitutionsMap.key(m_cryptText[i]) - LOWERBOUND) - mapOffset++) %
                  (26);

            // to hack the modulo operator
            if (tmp < 0)
            {
                //Because tmp is negative adding it to UPPERBOUND subtracts it
                //Also plus 1 because -1 is the highest negative number
                m_clearText.append(UPPERBOUND + tmp + 1);
            }
            else
            {
                m_clearText.append(LOWERBOUND + tmp);
            }
        }
    }
}

/**
 * @brief CryptClassCaesar::buildMap fill the map with information
 */
void CryptClassCaesar::buildMap()
{
    bool ok = false;
    int rotor = getKey().toInt(&ok);

    if (ok == false || rotor < 1 || rotor > 5)
    {
        QMessageBox::warning(NULL, "Key invalid",
                             "The key for Enigma should only be a number between 1 and 5.");
        return;
    }

    rotor--;

    // Char Array to simple implement the rotor
    char rotors[5][27] =
    {
        "EKMFLGDQVZNTOWYHXUSPAIBRCJ",
        "AJDKSIRUXBLHWTMCQGZNPYFVOE",
        "BDFHJLCPRTXVZNYEIWGAKMUSQO",
        "ESOVPZJAYQUIRHXLNFTGKDCMWB",
        "VZBRGITYUPSDNHLXAWMJQOFECK"
    };

    // Clear substitution Map
    substitutionsMap.clear();

    for (int i = 0; i <= (UPPERBOUND - LOWERBOUND); i++)
    {
        substitutionsMap.insert((char)(LOWERBOUND + i), rotors[rotor][i]);
    }
}