C++ 如何正确地将std::string转换为无符号char[]数组*。我想我做错了,有人给我指出了正确的方向吗?

C++ 如何正确地将std::string转换为无符号char[]数组*。我想我做错了,有人给我指出了正确的方向吗?,c++,arrays,char,buffer,byte,C++,Arrays,Char,Buffer,Byte,我目前正在对一个网络协议进行反向工程,并编写了一个小型解密协议 我曾经将数据包的字节定义为无符号字符数组,如下所示: unsigned char buff[] = "\x00\xFF\x0A" etc. 为了避免每个包多次重新编译程序,我制作了一个小型GUI工具,它可以从字符串中获取\xFF表示法中的字节。我是这样做的: int length = int(stencString.length()); unsigned char *buff = new unsigned char[length+

我目前正在对一个网络协议进行反向工程,并编写了一个小型解密协议

我曾经将数据包的字节定义为无符号字符数组,如下所示:

unsigned char buff[] = "\x00\xFF\x0A" etc.
为了避免每个包多次重新编译程序,我制作了一个小型GUI工具,它可以从字符串中获取\xFF表示法中的字节。我是这样做的:

int length = int(stencString.length());
unsigned char *buff = new unsigned char[length+1];
memcpy(buff, stencString.c_str(), length+1);
当我调用我的函数时,当我使用Previor方法硬编码它时,它会给我一个正确的解密,但当我从字符串到数组memcpy时,它会给我垃圾,然后给我字符串的其余部分。令人毛骨悚然的部分?它们都有相同的打印输出

以下是我如何使用它:

以下是kdxalgo.h(c)Luigi Auriemma:

有人能给我指出正确的方向吗


谢谢

查看在硬编码版本的buff中使用以下内容时会发生什么

unsigned char buff[] =
"\\xd3\\x8c\\x38\\x6b\\x82\\x4c\\xe1\\x1e"
"\\x6b\\x7a\\xff\\x4c\\x9d\\x73\\xbe\\xab"
"\\x38\\xc7\\xc5\\xb8\\x71\\x8f\\xd5\\xbb"
"\\xfa\\xb9\\xf3\\x7a\\x43\\xdd\\x12\\x41"
"\\x4b\\x01\\xa2\\x59\\x74\\x60\\x1e\\xe0"
"\\x6d\\x68\\x26\\xfa\\x0a\\x63\\xa3\\x88";
我怀疑它将产生与您输入以下内容相同的输出:
\xd3\x8c\x38\x6b\x82\x4c\xe1\x1e\x6b\x7a\xff\x4c\x9d\x73\xbe\xab\x38\xc7\xc5\xb8\x71\xb5\xfa\xb9\xf3\x7a\x43\x43\xdd\xdd\x42\x01\xa2\xa2\x79\x74\x60\x60\x76\x83\x83\x83\x83\x83>代码

编译器自动获取“\xd3”并将其转换为预期的基础二进制表示形式。您需要有一种将字符反斜杠x、d、3转换为相同二进制表示的方法


如果您确信将收到格式正确的输入,那么答案并不难:

unsigned char c2h(char ch)
{
    switch (ch)
    {
        case '0': return  0;
        case '1': return  1;
        case '2': return  2;
        case '3': return  3;
        case '4': return  4;
        case '5': return  5;
        case '6': return  6;
        case '7': return  7;
        case '8': return  8;
        case '9': return  9;
        case 'a': return 10;
        case 'b': return 11;
        case 'c': return 12;
        case 'd': return 13;
        case 'e': return 14;
        case 'f': return 15;
    }
}

std::string handle_hex(const std::string& str)
{
    std::string result;

    for (size_t index = 0; index < str.length(); index += 4) // skip to next hex digit
    {
        // str[index + 0] is '\\' and str[index + 1] is 'x'
        unsigned char ch = c2h(str[index+2]) * 16 + c2h(str[index+3]);
        result.append((char)ch);
    }

    return result;
}
无符号字符c2h(字符ch)
{
开关(ch)
{
案例“0”:返回0;
案例“1”:返回1;
案例“2”:返回2;
案例“3”:返回3;
案例“4”:返回4;
案例“5”:返回5;
案例“6”:返回6;
案例“7”:返回7;
案例“8”:返回8;
案例“9”:返回9;
案例“a”:返回10;
案例“b”:返回11;
案例“c”:返回12;
案例“d”:返回13;
案例“e”:返回14;
案例“f”:返回15;
}
}
字符串句柄(常量std::string&str)
{
std::字符串结果;
对于(size_t index=0;index

再次假设格式完美,因此没有错误处理。我知道这个答案会让我失去一些分数,因为这不是最好的方法,但我想让算法尽可能容易理解。

正如Jeffery指出的,问题是编译器处理
\xd3
并生成一个具有该值的字符,但是当你读入一个字符串
\xd3
时,你实际上在读4个字符:
\
x
d
3

您需要读取字符串,然后将其解析为有效内容。对于一种简单的方法,您可以更改格式,使输入是一个以空格分隔的字符序列,编码为
0xd3
(因为这非常容易解析):


您是否进行了二进制比较,以确保硬编码版本与您的“解码”版本真正匹配?除了将其保留在字符串中,您还有什么优势?(顺便说一句,对字符缓冲区使用
std::vector
)我不认为这是你的问题,但是你可以不使用c_str()函数从std::string中复制出缓冲区,调用.data()成员函数:
memcpy(buff,stencString.data(),length)
等等,我接下来要做什么?你完全正确,它产生同样错误的输出@戴维斯坦库:你需要解析字符串并转换成你想要的字符。这应该不会太复杂:)如果你能允许更改格式,它实际上可以很简单。
std::string buffer;
std::string input( "0xd3 0x8c 0x38" ); // this would be read
std::istringstream in( input );
in >> std::hex;
std::copy( std::istream_iterator<int>( in ),
           std::istream_iterator<int>(),
           std::back_inserter( buffer ) );
int value_of_hex( char ch ) {
   if (ch >= '0' && ch <= '9')
      return ch-'0';
   if (tolower(ch) >= 'a' && tolower(ch) <= 'f')
      return 10 + toupper(ch) - 'a';
   // error
   throw std::runtime_error( "Invalid input" );
}
value = value_of_hex( ch1 )*16 + value_of_hex( ch2 );