Ниже приведен код для простого шифрования XOR. Он запрашивает у пользователя сообщение, за которым следует ключ, а затем шифрует сообщение ключом в 128-битных блоках.
Когда короткий ввод (например: test
) вводится как сообщение (первое cin
вызов), программа приостанавливает и ожидает ввода с клавиши, как и ожидалось.
Если я введу более длинное и культурно насыщенное сообщение (например, Now is the winter of our discontent
), программа немедленно возвращается из cin
вызов, не в состоянии принять вход. Есть идеи, почему это происходит?
#include <iostream>
#include <iomanip>
#include "string.h"#include "assert.h"
using std::cout;
using std::cin;
using std::endl;
using std::string;
string getMessage();
string getPassphrase();
string setKey(string key);
string xorECB(string msg, string key);
char knownPlaintext(char ciphertext, char plaintext);
struct cipherblock
{
char block[16];
};
int main(void)
{
string plaintext = getMessage();
string key = getPassphrase();
string ciphertext = xorECB(plaintext, key);
cout << plaintext.size() << endl;
cout << key.size() << endl;
cout << ciphertext.size() << endl;
return 0;
}
string getMessage()
{
cout << "Message: ";
string msg;
cin >> msg;
cin.ignore();
return msg;
}
string getPassphrase()
{
cout << "Key: ";
string key;
cin >> key;
cin.ignore();
return setKey(key);
}
string setKey(string key)
/// Create 128-bit key from arbitrary-length ASCII passphrase.
{
if (key.size() == 16)
return key;
if (key.size() < 16)
key += key.substr(0, 16 - key.size());
else
{
string keyxor = key.substr(16, key.size());
key.erase(16, key.size() - 16);
for (int i; i < keyxor.size(); i++)
key[i] ^= keyxor[i];
}
return setKey(key); // keys shorter than 8 bytes need to be built recursively
}
string xorECB(string msg, string key)
/// XOR cipher operating in ECB mode, 128-bit block size
{
assert(key.size() == 16); // 16 bytes = 128 bits
//for(int i = 0; i < msg.size(); i++)
//msg[i] ^= key;
for (int i = 0; i < msg.size() / sizeof(cipherblock); i++)
{
cipherblock *block = (cipherblock*)msg[0];
for (int idx = 0; idx < key.size(); idx++)
block->block[idx] ^= (char)key[idx];
block++;
}
return msg;
}
char knownPlaintext(char ciphertext, char plaintext)
{
return ciphertext ^ plaintext;
}
Любые другие комментарии и критика также приветствуются! Спасибо!
Оператор ввода >>
упоры на пробел (то есть пробелы между вашими словами). Если вы хотите получить целую строку, вы должны использовать, например, std::getline
.
cin перестанет обрабатывать ваш ввод после первого пробела, который он обнаружит. Таким образом, вы получите только одно слово в качестве ввода.