c_str() 正在终止我的加密消息,有没有办法绕过这个?
c_str() is terminating my encrypted message is there a way to bypass this?
我正在使用 RSA 加密邮件。
如果我尝试在本地 encrypt/decrypt 消息,一切正常,但是,当将字符串转换为 void constant*
以便像这样使用 socket::send
方法时,
int sendRes = send(socket, tempMessage.c_str(), tempMessage.size() + 1, 0);
发生以下情况,
我原来的字符串,tempMessage
"_��JE�-��6����Pr��[͉dZ%�"
当使用 tempMessage.c_str()
时, 被截断为这个
"_��JE
我知道这个是因为,在加密过程中,有一个[=16=]
符号被附加在一次或几次之间,因此在使用时终止那里的一切c_str().
我也知道它发生在使用 send() 之前,我把它放在这里是为了让你首先知道我为什么要使用 c_str()。
有办法绕过这个吗?或解决方法?
我看过 this 之前的回答,但对我的情况没有帮助,也找不到任何其他解决方案。
在此先感谢您的帮助!
这是一个简单的例子
- 在包含空字符的字符串上显示
c_str()
的问题。
- sending/receiving 个字符串的两个原语。
想法是 send/receive 字符串的长度在实际字符之前的固定字节数上。
/**
g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
-pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <iostream>
#include <string>
#include <stdexcept>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
ssize_t
send_all(int sockfd,
const void *buf,
size_t len,
int flags)
{
const auto *p=static_cast<const char *>(buf);
auto remaining=len;
while(remaining)
{
const auto r=send(sockfd, p, remaining, flags);
if(r<0)
{
return r;
}
remaining-=r;
p+=r;
}
return len-remaining;
}
ssize_t
recv_all(int sockfd,
void *buf,
size_t len,
int flags)
{
char *p=static_cast<char *>(buf);
auto remaining=len;
while(remaining)
{
const auto r=recv(sockfd, p, remaining, flags);
if(r<0)
{
return r;
}
if(r==0) // EOF
{
break;
}
remaining-=r;
p+=r;
}
return len-remaining;
}
void
send_string(int sockfd,
const std::string &str,
int flags)
{
const auto length=htonl(std::int32_t(size(str)));
if(send_all(sockfd, &length, sizeof(length), flags)!=sizeof(length))
{
throw std::runtime_error{"cannot send length"};
}
if(send_all(sockfd, data(str), size(str), flags)!=
static_cast<ssize_t>(size(str)))
{
throw std::runtime_error{"cannot send string"};
}
}
std::string
recv_string(int sockfd,
int flags)
{
auto str=std::string{};
auto length=std::int32_t{};
const auto r=recv_all(sockfd, &length, sizeof(length), flags);
if(r==0) // EOF
{
return str;
}
if(r!=sizeof(length))
{
throw std::runtime_error{"cannot receive length"};
}
str.resize(ntohl(length));
if(recv_all(sockfd, data(str), size(str), flags)!=
static_cast<ssize_t>(size(str)))
{
throw std::runtime_error{"cannot receive string"};
}
return str;
}
int
main()
{
auto msg=std::string{};
msg+="there is a nul-char...";
msg+='[=10=]';
msg+="in the middle!";
std::cout << "as a string <" << msg << ">\n";
std::cout << "as a const char * <" << msg.c_str() << ">\n";
std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
int fd[2];
if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fd)<0)
{
throw std::runtime_error{"socketpair() failure"};
}
for(auto i=0; i<5; ++i) // very few to fit in internal buffer
{
send_string(fd[1], "message number "+std::to_string(i+1), 0);
}
close(fd[1]);
for(;;)
{
const auto s=recv_string(fd[0], 0);
if(empty(s))
{
break;
}
std::cout << '[' << s << "]\n";
}
close(fd[0]);
return 0;
}
/**
as a string <there is a nul-char...in the middle!>
as a const char * <there is a nul-char...>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[message number 1]
[message number 2]
[message number 3]
[message number 4]
[message number 5]
**/
最终,这是一个更容易解决的问题。
由于所有消息都按照相同的类型进行加密,因此加密部分的位长度将始终相同。
在我的例子中,这是 256
,这意味着我现在可以毫无问题地发送-接收,因为我现在知道了真正的字符串长度。
如果不是这种情况,我会选择@prog-fh answer
我正在使用 RSA 加密邮件。
如果我尝试在本地 encrypt/decrypt 消息,一切正常,但是,当将字符串转换为 void constant*
以便像这样使用 socket::send
方法时,
int sendRes = send(socket, tempMessage.c_str(), tempMessage.size() + 1, 0);
发生以下情况,
我原来的字符串,tempMessage
"_��JE
tempMessage.c_str()
时,被截断为这个
"_��JE 我知道这个是因为,在加密过程中,有一个 我也知道它发生在使用 send() 之前,我把它放在这里是为了让你首先知道我为什么要使用 c_str()。 有办法绕过这个吗?或解决方法? 我看过 this 之前的回答,但对我的情况没有帮助,也找不到任何其他解决方案。 在此先感谢您的帮助![=16=]
符号被附加在一次或几次之间,因此在使用时终止那里的一切c_str().
这是一个简单的例子
- 在包含空字符的字符串上显示
c_str()
的问题。 - sending/receiving 个字符串的两个原语。
想法是 send/receive 字符串的长度在实际字符之前的固定字节数上。
/**
g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
-pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <iostream>
#include <string>
#include <stdexcept>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
ssize_t
send_all(int sockfd,
const void *buf,
size_t len,
int flags)
{
const auto *p=static_cast<const char *>(buf);
auto remaining=len;
while(remaining)
{
const auto r=send(sockfd, p, remaining, flags);
if(r<0)
{
return r;
}
remaining-=r;
p+=r;
}
return len-remaining;
}
ssize_t
recv_all(int sockfd,
void *buf,
size_t len,
int flags)
{
char *p=static_cast<char *>(buf);
auto remaining=len;
while(remaining)
{
const auto r=recv(sockfd, p, remaining, flags);
if(r<0)
{
return r;
}
if(r==0) // EOF
{
break;
}
remaining-=r;
p+=r;
}
return len-remaining;
}
void
send_string(int sockfd,
const std::string &str,
int flags)
{
const auto length=htonl(std::int32_t(size(str)));
if(send_all(sockfd, &length, sizeof(length), flags)!=sizeof(length))
{
throw std::runtime_error{"cannot send length"};
}
if(send_all(sockfd, data(str), size(str), flags)!=
static_cast<ssize_t>(size(str)))
{
throw std::runtime_error{"cannot send string"};
}
}
std::string
recv_string(int sockfd,
int flags)
{
auto str=std::string{};
auto length=std::int32_t{};
const auto r=recv_all(sockfd, &length, sizeof(length), flags);
if(r==0) // EOF
{
return str;
}
if(r!=sizeof(length))
{
throw std::runtime_error{"cannot receive length"};
}
str.resize(ntohl(length));
if(recv_all(sockfd, data(str), size(str), flags)!=
static_cast<ssize_t>(size(str)))
{
throw std::runtime_error{"cannot receive string"};
}
return str;
}
int
main()
{
auto msg=std::string{};
msg+="there is a nul-char...";
msg+='[=10=]';
msg+="in the middle!";
std::cout << "as a string <" << msg << ">\n";
std::cout << "as a const char * <" << msg.c_str() << ">\n";
std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
int fd[2];
if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fd)<0)
{
throw std::runtime_error{"socketpair() failure"};
}
for(auto i=0; i<5; ++i) // very few to fit in internal buffer
{
send_string(fd[1], "message number "+std::to_string(i+1), 0);
}
close(fd[1]);
for(;;)
{
const auto s=recv_string(fd[0], 0);
if(empty(s))
{
break;
}
std::cout << '[' << s << "]\n";
}
close(fd[0]);
return 0;
}
/**
as a string <there is a nul-char...in the middle!>
as a const char * <there is a nul-char...>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[message number 1]
[message number 2]
[message number 3]
[message number 4]
[message number 5]
**/
最终,这是一个更容易解决的问题。
由于所有消息都按照相同的类型进行加密,因此加密部分的位长度将始终相同。
在我的例子中,这是 256
,这意味着我现在可以毫无问题地发送-接收,因为我现在知道了真正的字符串长度。
如果不是这种情况,我会选择@prog-fh answer