-
Notifications
You must be signed in to change notification settings - Fork 1k
/
Copy pathPlayFair_Cipher.cpp
159 lines (148 loc) · 5.18 KB
/
PlayFair_Cipher.cpp
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
About Play Fair Cipher: In Play fair, The Key Matrix will be always 5x5 dimension. It neither depends on key nor on plain text.
We have to build always a 5x5 matrix. Now, this 5x5 grid of matrix consists of alphabets(a-z) which is used to encrypt/decrypt the text.
Each of the 25 alphabets must be unique and we have to assume I and J as a single char(it's our choice to select I or J).
Because, 5x5 grid contains only 25 slots. If the plaintext contains J/I, then it is replaced by I/J(based on our assumption).
Rules:
1. Form a rectangle with the two letters and take the letters on the horizontal opposite corner of the rectangle.
2. If both the letters are in the same row: Take the letter to the right of each one (going back to the leftmost if at the rightmost position).
3. If both the letters are in the same column: Take the letter below each one (going back to the top if at the bottom).
*/
#include <bits/stdc++.h>
#define dim 5 //dimension 5x5
std::string resulttext;
char matrix[dim][dim], choosechar(int a, int b);
bool chooseindex(char l, int &a, int &b);
void formmatrix(std::string k, bool ij);
// Argument e_d: Encryption or Decryption(true/false)
std::string play_fair(std::string key, std::string text, bool ij, int e_d)
{
formmatrix(key, ij);
// Placing I/J in one cell in matrix
for (std::string::iterator i = text.begin(); i != text.end(); ++i)
{
*i = toupper(*i);
if (*i < 65 || *i > 90)
continue;
if (*i == 'J' && ij)
*i = 'I';
else if (*i == 'Q' && !ij)
continue;
resulttext += *i;
}
// For Encryption
if (e_d)
{
std::string temptext = "";
size_t len = resulttext.length();
for (size_t x = 0; x < len; x += 2)
{
temptext += resulttext[x];
if (x + 1 < len)
{
if (resulttext[x] == resulttext[x + 1])
temptext += 'X';
temptext += resulttext[x + 1];
}
}
resulttext = temptext;
}
if (resulttext.length() & 1)
resulttext += 'X';
// for Indexes
int a, b, c, d;
// Result strings
std::string tempresult = "";
// Iterating through out the string(all chars)
for (std::string::const_iterator i = resulttext.begin(); i != resulttext.end(); ++i)
{
// Selecting the indexes from matrix
if (chooseindex(*i++, a, b))
if (chooseindex(*i, c, d))
{
if (a == c)
{
tempresult += choosechar(a, b + e_d);
tempresult += choosechar(c, d + e_d);
}
else if (b == d)
{
tempresult += choosechar(a + e_d, b);
tempresult += choosechar(c + e_d, d);
}
else
{
tempresult += choosechar(c, b);
tempresult += choosechar(a, d);
}
}
}
resulttext = tempresult;
return resulttext;
}
// Selecting char from matrix with provided indexes(parameters)
char choosechar(int a, int b)
{
return matrix[(b + dim) % dim][(a + dim) % dim];
}
// Validation
bool chooseindex(char character, int &a, int &b)
{
for (int y = 0; y < dim; ++y)
for (int x = 0; x < dim; ++x)
if (matrix[y][x] == character)
{
a = x;
b = y;
return true;
}
return false;
}
/*
First, We have fill the matrix with letters/characters of key without repeating any character(skip duplicates).
(*) = empty
fill the other slots with remaining characters(a-z) sequentially. Place I/J in one slot(index). Now the resultant will be our Key matrix
*/
void formmatrix(std::string key, bool ij)
{
if (key.length() < 1)
key = "";
key += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::string tempKey = "";
for (std::string::iterator i = key.begin(); i != key.end(); ++i)
{
*i = toupper(*i);
if (*i < 65 || *i > 90)
continue;
if ((*i == 'J' && ij) || (*i == 'Q' && !ij))
continue;
if (tempKey.find(*i) == -1)
tempKey += *i;
}
copy(tempKey.begin(), tempKey.end(), &matrix[0][0]);
}
// Driver code starts
int main(int argc, char *argv[])
{
std::string key = "harry";
std::string plaintext = "my name is ravi";
std::string encryptedtext, decryptedtext;
std::cout << "\nPlain Text is : " << plaintext;
// Encryption Process starts
encryptedtext = play_fair(key, plaintext, true, 1);
std::cout << "\n\nEncrypted Text is : " << encryptedtext; // Displaying Encrypted Key
// Decryption Process starts
decryptedtext = play_fair(key, encryptedtext, true, -1);
decryptedtext = decryptedtext.substr(0, decryptedtext.length() / 2);
std::cout << "\nDecrypted Text is: " << decryptedtext; // Displaying Decrypted Key
return 0;
}
/*
Sample Input:
Key: harry
plainText: my name is ravi
Sample Output:
Plain Text is : my name is ravi
Encrypted Text is : SFKBLFMOYRUK
Decrypted Text is: MYNAMEISRAVI
*/