Создание программы шифрования на C с использованием только массивов. Не уверен, как продолжить

#c

#c

Вопрос:

РЕДАКТИРОВАТЬ ПРИМЕЧАНИЕ * Я не пытаюсь создать что-то для использования. Я создаю это, чтобы получить четкое представление о том, как работают массивы в c .

Здравствуйте, я создаю простую программу шифрования. Это моя первая программа (для развлечения), и я немного смущен тем, как продолжить с этим.(У меня есть некоторый код, но, черт возьми, я застрял!)

Итак, прежде всего, я собираюсь использовать метод шифрования ROT-N.

По сути, я хочу, чтобы пользователь вводил сообщение, и сообщение подчинялось этим правилам:

1) Сдвиньте каждый символ / цифру, которые вводит пользователь, и сдвиньте его вправо на 8-15 символов / цифр, и пусть он повторяется. Я не хочу переходить к списку расширенных символов.

2) Если пользователь вводит строчную букву, я хочу, чтобы она стала строчной.

3) Последний бит — я хочу, чтобы пробелы тоже были зашифрованы. Программа должна указывать, где находятся пробелы.

Пример. Если пользователь вводит «Сообщение 0600»

Зашифрованное сообщение должно гласить «8umaaiom3933 amp; 8»

«8» в начале говорит о том, насколько смещены буквы. «umaaiom3933» — это зашифрованное сообщение. amp; означает, что сообщение завершено, а последняя «8» указывает, где находится пробел.

С чем у меня возникли проблемы:

1) Попытка принять сообщение от пользователя и поместить его в массив (каждый символ в сообщении становится символом в массиве)

2) Берем эти символы и добавляем значение смещения для другого значения

Это то, что у меня есть до сих пор.

 #include <iostream> 
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    srand(time(0));
    int n = 13;
    cout << n << endl;
    int r = n   255;
    string mes, emes;
    cout << "Please enter the message: " << endl;
    getline(cin,mes);
    int len = mes.length();
    for(int i = 0; i <= len; i  )
    {
        mes[i]  = n;
    }
    cout << mes;





    return 0;
}
  

Комментарии:

1. Вы не можете назначить a std::string массиву (определенно не так), вам придется скопировать его (например: using strncpy ). Однако вы также можете просто перебирать содержимое std::string , нет необходимости явно копировать его в char массив.

2. Перетасовка символов в алфавите неэффективна и сложна, почему бы вам не использовать старый добрый xor ? Вы можете сделать действительно хорошее шифрование, немного изобретательное в этом.

3. Кроме того, rmes = message отсутствует ; , и я не думаю, что копирование a std::string в a char[1000] таким образом безопасно или законно. Используйте strcpy_s(rmes, 1000, message.c_str()); . или отбросьте избыточность памяти и используйте указатели char *rmes = message.c_str(); .

4. Извините, я не знаю, как использовать xor. Я поставил точку с запятой. Спасибо, что напомнили мне!

5. Xor — это побитовая операция, которая выполняет 0^0=0 1^1=0 и все остальное =1 . Если вы выполняете итерацию каждого символа, y = x^123 например, вы генерируете строку, которая не может быть прочитана, если вы снова передадите ее через тот же алгоритм, она вернется к исходной строке. Это очень просто.

Ответ №1:

По сути, строка C представляет собой простую область памяти с форматом

‘H’ ‘e’ ‘l’ ‘l’ ‘o»-‘ ‘w’ ‘o’ ‘r’ ‘l’ ‘d’ 0

Итак, предположим, что у нас есть функция char encrypt(char ch), которая шифрует символ.

 int i;
char *str; /* the input string */

for(i=0;str[i] != 0; i  )
  str[i] = encrypt(str[i]);
  

Однако строки стандартной библиотеки шаблонов C немного отличаются. К ним подключено гораздо больше оборудования. Хотя вы можете попытаться изменить их на месте, на самом деле вам лучше привыкнуть думать о них как о неизменяемых и постоянных. Однако вы можете создать его с помощью push_back .

Итак

 std::string encryptstring(const std::string amp;plaintext)
{
   size_t i;  // should be int or index_t, very poor choice of name by the C   folks
   std::string answer;

    for(i=0;i<plaintext.length();i  )
    {
        answer.push_back( encrypt(plaintext[i]));
    }

    return answer;
}
  

Это идиоматический способ сделать это. C допускает прямой доступ к содержимому строки, но, как правило, препятствует этому.

Комментарии:

1. Спасибо! Это очень помогает!

Ответ №2:

Я прочитал все ваши комментарии. Они были очень полезны, спасибо! Я действительно потратил время на размышления и исследования. Я смог завершить программу. Вот оно!

Самая большая проблема, с которой я столкнулся, заключалась в том, что я не понимал, что в c строка записывается непосредственно в массив символов

 #include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <sstream>
using namespace std;

int main()

{
    srand(time(0));

    string imes, omes;
    int len;
    int n = rand()%(15 - 8   1)   8;

    cout << "Please Enter a Message:  " << endl;
    getline (cin, imes);    
    std::ostringstream oss;
    len = imes.length();

    for (int i = 0; i < len; i  )
    {
        imes[i] = tolower(imes[i]);
        if (imes[i] >= 'a' amp;amp; imes[i] <= 'z')
        {
            omes  = ((imes[i] - 'a'   n) % 26)   'a';
        }
        if (imes[i] >= '0' amp;amp; imes[i] <= '9')
        {
            omes  = ((imes[i] - '0'   n) % 10)   '0';
        }   
        else 

        if(imes[i] == ' ')
        { 
            if (imes[i - 1] >= 'a' amp;amp; imes[i - 1] <= 'z')
            {
                omes  = ((imes[i - 1] - 'a'   4) % 26)   'a';
            }
            else
            if (imes[i - 1] >= '0' amp;amp; imes[i - 1] <= '9')
            {
                omes  = ((imes[i - 1] - '0'   4) % 10)   '0';
            }
            oss << '#' << i;
        }
    }

    omes << 'amp;' << oss.str() << endl;
    cout << "The message has been encrypted and transmitted" << endl;
    outdata.close();
    return 0;
}