@EgaNator
Учусь на программиста

Как расположить буквы русского алфавита в порядке от 1 и 32 и работать с их порядковыми номерами?

Реализовал программу для шифрования по алгоритму RSA, всё работает правильно. Только у меня выполняется кодирование согласно таблице кодировки Windows 1251. По заданию же необходимо, чтобы было только 32 символа (заглавные русские буквы). И чтобы они имели порядковые номера от 1 до 32 соответственно (как в алфавите). Пытаюсь так сделать, но не выходит.
В данной программе ещё всё хорошо работает с английскими буквами и с цифрами, а с кириллицей нет.

Подскажите, пожалуйста, как можно это реализовать?

Полный код программы:
#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;
    }
  • Вопрос задан
  • 96 просмотров
Пригласить эксперта
Ответы на вопрос 2
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Буквы русского алфавита (кроме 'ё') - идут в алфавитном порядке практически во всех кодировках.

Т.е. вам надо просто вычесть код буквы 'а' из полученной буквы и вы получите число от 0 до 31. Если вам надо с 1 до 32, то прибавьте 1.

Осталось понять, какой код у буквы 'а'. Это зависит от кодировки. Можете в вашей программе вывести введенные буквы, преобразовав их к int. Передайте ей буквы 'а' и вы получите число, которое вам можно захардкодить в вашей программе.
Ответ написан
Комментировать
@rPman
char* mychars="абвгдеёжзийклмнопрстуфхчшщьыъэюя";

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

если надо прямо с 1 то добавь фиктивный символ какой в начало, пробел например

p.s. приведенный пример для однобайтовой кодировки
если нужны мультибайтовые то wchar_t (или std::wstring) и строку задать с литерой L"абвг...."
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы