E
E
Egor Nameles2022-01-28 12:34:10
C++ / C#
Egor Nameles, 2022-01-28 12:34:10

How to arrange the letters of the Russian alphabet in order from 1 and 32 and work with their serial numbers?

Implemented a program for encryption using the RSA algorithm, everything works correctly. Only I am encoding according to the Windows encoding table 1251. According to the assignment, it is necessary that there be only 32 characters (capital Russian letters). And so that they have serial numbers from 1 to 32, respectively (as in the alphabet). I'm trying to do this, but it doesn't work.
In this program, everything still works well with English letters and numbers, but not with Cyrillic.

Can you please tell me how to implement this?

Full program code:

#include <iostream>
#include <math.h>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
using namespace std;
 
 
bool isPrime(long int prime);
long int calculateE(long int t);
long int greatestCommonDivisor(long int e, long int t);
long int calculateD(long int e, long int t);
long int encrypt(long int i, long int e, long int n);
long int decrypt(long int i, long int d, long int n);
 
int main()
{
    //setlocale(LC_ALL, "Russian");
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    long int p, q, n, t, e, d;
 
    long int encryptedText[100];
    memset(encryptedText, 0, sizeof(encryptedText));
 
    long int decryptedText[100];
    memset(decryptedText, 0, sizeof(decryptedText));
 
    bool flag;
    string msg;
 
    // Cоздание открытого и секретного ключей
    // 1. Выбираются два различных случайных простых числа p и q заданного размера
 
    do
    {
        cout << "Введите простое число p:";
        cin >> p;
        flag = isPrime(p);
 
        if (flag == false)
        {
            cout << "\nОшибка ввода (Данное число не является простым)\n" << endl;
        }
    } while (flag == false);
 
 
    do
    {
        cout << "Введите простое число q:";
        cin >> q;
        flag = isPrime(q);
 
        if (flag == false)
        {
            cout << "\nОшибка ввода (Данное число не является простым)\n" << endl;
        }
    } while (flag == false);
 
    // 2. Вычисляется их произведение n = p*q, которое называется модулем.
    n = p * q;
    cout << "\nРезультат произведения n = p*q = " << n << endl;
 
    // 3. Вычисляется значение функции Эйлера от числа n: φ(n) = (p−1)⋅(q−1)
    t = (p - 1) * (q - 1);
    cout << "Результат вычисления функции Эйлера: t = " << t << endl;
 
    // 4. Выбирается целое число e ( 1 < e < φ(n) ), взаимно простое со значением функции Эйлера (t)
    //    Число e называется открытой экспонентой
    e = calculateE(t);
 
    // 5. Вычисляется число d, мультипликативно обратное к числу e по модулю φ(n), то есть число, удовлетворяющее сравнению:
    //    d ⋅ e ≡ 1 (mod φ(n))
    d = calculateD(e, t);
 
    // 6. Пара {e, n} публикуется в качестве открытого ключа RSA
    cout << "\nОткрытый ключ (e = " << e << ", n = " << n << ")" << endl;
 
    // 7. Пара {d, n} играет роль закрытого ключа RSA и держится в секрете
    cout << "Закрытый ключ (d = " << d << ", n = " << n << ")" << endl;
 
 
    cout << "\nВведите сообщение: " << endl;
    cin.ignore();
    getline(std::cin, msg);
    cout << "\nВаше сообщение: " << msg << endl;
 
 
    // encryption
    for (long int i = 0; i < msg.length(); i++)
    {
        encryptedText[i] = encrypt(msg[i], e, n);
    }
 
    cout << "\nЗашифрованное сообщение:";
 
    for (long int i = 0; i < msg.length(); i++)
    {
        printf("%c", (char)encryptedText[i]);
    }
 
    //decryption
    for (long int i = 0; i < msg.length(); i++)
    {
        decryptedText[i] = decrypt(encryptedText[i], d, n);
    }
 
    cout << "\n\nРасшифрованное сообщение:";
 
    for (long int i = 0; i < msg.length(); i++)
    {
        printf("%c", (char)decryptedText[i]);
    }
 
    cout << endl << endl;
 
    _getch();
    return 0;
}
 
bool isPrime(long int prime)
{
    long int i, j;
    j = (long int)sqrt((long double)prime);
 
    for (i = 2; i <= j; i++)
    {
        if (prime % i == 0)
        {
            return false;
        }
    }
    return true;
}
 
long int calculateE(long int t)
{
    // Выбирается целое число e ( 1 < e < t ) // взаимно простое со значением функции Эйлера (t)
 
    long int e;
    for (e = 2; e < t; e++)
    {
        if (greatestCommonDivisor(e, t) == 1)
        {
            return e;
        }
    }
    return -1;
}
 
long int greatestCommonDivisor(long int e, long int t)
{
    while (e > 0)
    {
        long int myTemp;
 
        myTemp = e;
        e = t % e;
        t = myTemp;
    }
    return t;
}
 
long int calculateD(long int e, long int t)
{
    // Вычисляется число d, мультипликативно обратное к числу e по модулю φ(n), то есть число, удовлетворяющее сравнению:
    //    d ⋅ e ≡ 1 (mod φ(n))
    long int d;
    long int k = 1;
 
    while (1)
    {
        k = k + t;
        if (k % e == 0)
        {
            d = (k / e);
            return d;
        }
    }
}
 
 
long int encrypt(long int i, long int e, long int n)
{
    long int current, result;
 
    current = i - 65;
    result = 1;
 
    for (long int j = 0; j < e; j++)
    {
        result = result * current;
        result = result % n;
    }
    return result;
}
 
long int decrypt(long int i, long int d, long int n)
{
    long int current, result;
 
    current = i;
    result = 1;
 
    for (long int j = 0; j < d; j++)
    {
        result = result * current;
        result = result % n;
    }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
W
Wataru, 2022-01-28
@wataru

The letters of the Russian alphabet (except for 'e') are in alphabetical order in almost all encodings.
Those. you just need to subtract the code of the letter 'a' from the resulting letter and you will get a number from 0 to 31. If you need from 1 to 32, then add 1. It
remains to figure out what code the letter 'a' has. It depends on the encoding. You can display the entered letters in your program by converting them to int. Give it the letters 'a' and you'll get a number that you can hardcode into your program.

R
rPman, 2022-01-28
@rPman

char* mychars="абвгдеёжзийклмнопрстуфхчшщьыъэюя";

mychars[0] - первая буква 'а'
mychars[6] - буква 'ё'

if you need it directly from 1, then add a fictitious character to the beginning, a space, for example
ps, the example given for a single-byte encoding
, if multibyte encodings are needed, then wchar_t (or std::wstring) and set the string with the letter L "abvg...."

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question