Polibio cryptography with c++

Can you help me how create Polibio cryptography with c++ ?
Many thanks!!
https://www.cmswiki.net/risorse-sviluppo/codice-poligrafico-la-scacchiera-di-polibio
google translate:
"The oldest polygraphic code (multiple substitution) is probably Polybius' chessboard. The Greek historian Polybius (~200-118 BC), in his Histories (Book X), describes a cipher that he attributes to his contemporaries Cleoxenus and Democleitus: the idea is to cipher a letter with a pair of numbers between 1 and 5, according to the description of a 5x5 chessboard.

The message was thus transmitted with two groups of five torches (e.g. 1.5 = one torch lit on the right, five on the left) and could be any length. A chessboard for the modern alphabet (merging together the two infrequent characters k and q to obtain a total of 25 codes) is that in Tab. 2.

polybius chessboard
Example:

v i e n s u b s e q u e n t s
5124153424434513244435

The Polybius chessboard has some important features, namely the reduction in the number of characters used in the cipher message, the conversion into numbers and the reduction of a symbol into two parts that can be used separately. Its importance in the history of cryptography lies in being the basis of other ciphers such as the Playfair Cipher or the Germanic field cipher used in the First World War.
"


In his Histories (Book X) Polybius describes an
important method of encryption. The idea is to
The idea is to encrypt a letter with a pair of numbers
between 1 and 5, based on a 5x5 matrix containing the letters of the alphabet.
letters of the alphabet.
Each letter is represented by two numbers,
looking at the row and column in which it is located. For
example, a=11 and r=42.
Example
Beware of rocks
11444415345524353415 11223224 431335223224
Its importance in the history of cryptography lies in being the basis of other ciphers such as
Its importance in the history of cryptography lies in being the basis for other ciphers such as the Playfair cipher (see section 3.1 ) or the Germanic field cipher used in the First World War.
Can you help me how create Polibio cryptography with c++ ?


What are the issues you are having? What have you done so far? Have you produced a design? How would you do this using pen/paper? What instructions would you give to someone else who knew nothing about this? Once you know the instructions to use (algorithm), then these are then incorporated into a program design and then the program is coded from the design.

Once you have the design and have started coding, post the code and say what issues you are having.
I know it is possible to represent the method with a two-dimensional array, but I can't do that because it is not a subject covered in school, I really don't know how to represent it without such an array ....


Last edited on
Double check with your professor about using a 2D array.

If you really must use a 1D array, you can simulate a 2D array. Given the desired row and function column, the corresponding item in a 1D array is at index row*5+column. If you know about functions and references, you could encode this in a function:
1
2
3
4
5
char array[25];
char &at2D(unsigned row, unsigned col) { return array[row*5+col]; }
...
char letter = at2D(2,3);  // read the letter at row 2, column 3
at2D(4,1) = 'd'  // set the letter at row 4, column 1 to 'd' 


This lets you find the letter at a particular row and column position, which is the main part of decrypting this cipher. The other structure you should create is one that gives you the row and column when you're given the letter (encrypting).
I really don't understand...
I find this code online but I don't understand the steps...

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
#include <cmath>
#include <iostream>
using namespace std;
void LetterToNumber(string str) {
   int R, C;
   for (int i = 0; str[i]; i++) {
      R = ceil((str[i] - 'a') / 5) + 1;
      C = ((str[i] - 'a') % 5) + 1;
      if (str[i] == 'k') {
         R = R - 1;
         C = 5 - C + 1;
      }
      else if (str[i] >= 'j') {
         if (C == 1) {
            C = 6;
            R = R - 1;
         }
         C = C - 1;
      }
      cout<<R<<C;
   }
   cout << endl;
}
int main() {
   string str = "k";
   cout<<"The numeric encryption of string '"<<str<<"' is : ";
   LetterToNumber(str);
   return 0;
}
Last edited on
You don't need an array for this problem. All you need really is a method of converting a row and column number into a char and a char into a row and column number.

Assuming 25 chars with a 5 x 5 matrix and that the chars are 1 to 25

If you have R and C numbers (1 - 5 inclusive) then that char number is (R - 1) * C

If you have the char number then R is (char / 5) + 1 where / is integer division
and C is (char mod 5) + 1 where mod is the remainder when divided by 5.

That's what

1
2
R = ceil((str[i] - 'a') / 5) + 1;
C = ((str[i] - 'a') % 5) + 1;


is doing.

The complication comes with the merging of k and q. It would be easier if y and z were merged! That's what the rest of the code in that function deals with. Adjusting R and C accordingly.

There's some issues with the function above. What if upper case letter or a non-letter?

Consider:

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
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

void LetterToNumber(const string& str)
{
	for (char ch : str) {
		if (isalpha(ch)) {
			if (isupper(ch))
				ch += 'a' - 'A';

			auto R {(ch - 'a') / 5 + 1};
			auto C {(ch - 'a') % 5 + 1};

			if (ch == 'k') {
				--R;
				C = 6 - C;
			} else
				if (ch >= 'j') {
					if (C == 1) {
						C = 6;
						--R;
					}

					--C;
				}

			cout << R << C << ' ';
		}
	}

	cout << '\n';
}

int main() {
	const string str {"aBCdefkxyz"};

	cout << "The numeric encryption of string '" << str << "' is : ";
	LetterToNumber(str);
}



The numeric encryption of string 'aBCdefkxyz' is : 11 12 13 14 15 21 25 53 54 55


Doing the reverse is similar.


That code you found on the internet isn't even correct. It converts i and j to 24. Then every letter is shifted one position to q. Q isn't the same as k.

Here's another way of doing it.
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
#include <cmath>
#include <iostream>
using namespace std;

string L2N(string str) {
    string result;
    for (int letter : str) {
	// Convert upper to lower case
	if (isupper(letter)) letter += 'a' - 'A';
	if (letter == 'q') {
	    letter = 'k';	// q moves to k's position
	} else if (letter > 'q') {
	    --letter;		// and anything greater than q moves down
	}
	letter -= 'a';		// convert to 0 to 25
	int R = letter / 5;
	int C = letter % 5;
	result += char(R + '1');
	result += char(C + '1');
	result += ' ';
    }
    return result;
}

int main() {
    string str;
    while (getline(cin, str)) {
	cout<<"Encrypted '"<<str<<"' to " << L2N(str) << '\n';
    }
   return 0;
}


Input:
abcde
fghij
knmno
pqrstu
vwxyz

Output:
Encrypted 'abcde' to 11 12 13 14 15
Encrypted 'fghij' to 21 22 23 24 25
Encrypted 'knmno' to 31 34 33 34 35
Encrypted 'pqrstu' to 41 31 42 43 44 45
Encrypted 'vwxyz' to 51 52 53 54 55

Topic archived. No new replies allowed.