C++. Как правильно конвертировать std::string (с массивом байт) в const std::char*
Я использую библиотеку CryptoPP для AES и RSA шифрования. И у меня возникает проблема при преобразовании std::string
в const std::char*
. На сколько я понимаю (по скриншотам ниже), проблема заключается в том, что функция .c_str()
обрезает строку в месте где встречается \0 или подобный символ.
Это функция шифрования:
string RSACryptography::Encrypt(string text) {
string cipher_text;
CryptoPP::StringSource(text, true, new CryptoPP::PK_EncryptorFilter(this->rng, this->publicKey, new CryptoPP::StringSink(cipher_text)));
return cipher_text;
}
Здесь я вызываю эту функцию:
int main() {
RSACryptography* CryptoRSA = new RSACryptography();
string cipher_text = CryptoRSA->Encrypt("hellO");
cout << "cipher text (string):\n" << cipher_text << "\n\n\n\n";
cout << "cipher text (string.c_str()):\n" << cipher_text.c_str() << endl;
}
CryptoPP шифрует текст и пишет его в строку. При обычном выводе строки, и дальнейшей передаче в функцию дешифрования всё работает отлично. Однако при попытке перевести std::string
в const std::char*
(чем по сути string и является) возникает вот такая проблема:
НО! В то же время, вероятность того, что функция .c_str()
обрежет строку, около 80%. То есть бывают случаи когда правильно возвращается вся строка (в последующем для функции const_cast).
Прошу, подскажите варианты того, как правильно конвертировать такую строку в const std::char*
.
P.S. Конвертировать std::string
в const std::char*
мне нужно для того, что бы я мог передать такую строку в Python. А для этого существует только 2 варианта типов: const std::char*
или const std::wchar_t*
P.S.S. Когда я дешифрую полученную строку, всё прекрасно работает. 10 раз запустил, 10 раз сработало.
Тогда я конвертирую шифрованную строку в const std::char*
и передаю её в функцию дешифрования. 10 раз запустил, 3 раза сработало(7 раз вылетело в ошибку) :(
int main() {
RSACryptography* RSACrypt = new RSACryptography();
string cipher_text = RSACrypt->Encrypt("hellO");
cout << "cipher text (string):\n" << cipher_text << "\n\n\n\n";
const char* cipher_text_char = const_cast<char*>(cipher_text.c_str());
cout << RSACrypt->Decipher(cipher_text_char);
}
Ответы (1 шт):
Проблема, как я понимаю, в том, что
string RSACryptography::Decipher(string text)
Теперь смотрите - если вы передаете string
- она идет со всеми нулевыми символами, все OK.
Но когда вы передаете аргументом char*
, то сначала вызывается конструктор строки string
для ее получения из char*
- а этот конструктор, видя нулевой символ, считает это окончанием строки!
Вот тут обрезание и происходит...
См. тут описание пятого конструктора - он полагает, что ему передается строка с завершающим нулевым символом.
Разжевываю.
Пусть после шифрования строка string cifer
состоит из каких-то байт, типа
05 3A 18 00 24 38 63
Если мы передает ее как строку для дешифровки - передаются все 7 байт. Но если мы передаем указатель на этот массив - то, поскольку функция принимает string
, а не char*
, сначала выполняется создание строки из этой последовательности символов. Конструктор string
создан так, что если он получает указатель - то считает, что это указатель на строку с завершающим нулевым символом. Он создает новую строк string
содержимое которой теперь
05 3A 18
Все! Потому что дальше - нулевой символ, строка считается завершенной - ну вот так написан конструктор!
Вот и несоответствие размеру, и обрезка по нулевому символу. Так понятно?