[英]Converting unsigned char * to hexstring
Below code takes a hex string(every byte is represented as its corresponidng hex value) converts it to unsigned char * buffer and then converts back to hex string.下面的代码采用一个十六进制字符串(每个字节都表示为其相应的十六进制值)将其转换为 unsigned char * 缓冲区,然后再转换回十六进制字符串。 This code is testing the conversion from unsigned char* buffer to hex string which I need to send over the network to a receiver process.此代码正在测试从 unsigned char* 缓冲区到十六进制字符串的转换,我需要通过网络将其发送到接收器进程。 I chose hex string as unsigned char can be in range of 0 to 255 and there is no printable character after 127. The below code just tells the portion that bugs me.我选择了十六进制字符串,因为 unsigned char 可以在 0 到 255 的范围内,并且在 127 之后没有可打印的字符。下面的代码只是告诉我困扰我的部分。 Its in the comment.它在评论中。
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
// converts a hexstring to corresponding integer. i.e "c0" - > 192
int convertHexStringToInt(const string & hexString)
{
stringstream geek;
int x=0;
geek << std::hex << hexString;
geek >> x;
return x;
}
// converts a complete hexstring to unsigned char * buffer
void convertHexStringToUnsignedCharBuffer(string hexString, unsigned char*
hexBuffer)
{
int i=0;
while(hexString.length())
{
string hexStringPart = hexString.substr(0,2);
hexString = hexString.substr(2);
int hexStringOneByte = convertHexStringToInt (hexStringPart);
hexBuffer[i] = static_cast<unsigned char>((hexStringOneByte & 0xFF)) ;
i++;
}
}
int main()
{
//below hex string is a hex representation of a unsigned char * buffer.
//this is generated by an excryption algorithm in unsigned char* format
//I am converting it to hex string to make it printable for verification pupose.
//and takes the hexstring as inpuit here to test the conversion logic.
string inputHexString = "552027e33844dd7b71676b963c0b8e20";
string outputHexString;
stringstream geek;
unsigned char * hexBuffer = new unsigned char[inputHexString.length()/2];
convertHexStringToUnsignedCharBuffer(inputHexString, hexBuffer);
for (int i=0;i<inputHexString.length()/2;i++)
{
geek <<std::hex << std::setw(2) << std::setfill('0')<<(0xFF&hexBuffer[i]); // this works
//geek <<std::hex << std::setw(2) << std::setfill('0')<<(hexBuffer[i]); -- > this does not work
// I am not able to figure out why I need to do the bit wise and operation with unsigned char "0xFF&hexBuffer[i]"
// without this the conversion does not work for individual bytes having ascii values more than 127.
}
geek >> outputHexString;
cout << "input hex string: " << inputHexString<<endl;
cout << "output hex string: " << outputHexString<<endl;
if(0 == inputHexString.compare(outputHexString))
cout<<"hex encoding successful"<<endl;
else
cout<<"hex encoding failed"<<endl;
if(NULL != hexBuffer)
delete[] hexBuffer;
return 0;
}
// output
// can some one explain ? I am sure its something silly that I am missing.
The output of an unsigned char
is like the output of a char
which obviously does not what the OP expects. unsigned char
的输出就像一个char
的输出,这显然不是 OP 所期望的。
I tested the following on coliru:我在coliru上测试了以下内容:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned char)0xc0 << '\n';
return 0;
}
and got:并得到:
Output of (unsigned char)0xc0: 0�
This is caused by the std::ostream::operator<<()
which is chosen out of the available operators.这是由从可用运算符中选择的std::ostream::operator<<()
引起的。 I looked on cppreference我查看了 cppreference
and found并发现
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
unsigned char ch );
in the former (with a little bit help from MM).在前者(在MM的帮助下)。
The OP suggested a fix: bit-wise And with 0xff
which seemed to work. OP 提出了一个修复方法:按位和0xff
似乎有效。 Checking this in coliru.com:在coliru.com中检查:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (0xff & (unsigned char)0xc0) << '\n';
return 0;
}
Output:输出:
Output of (unsigned char)0xc0: c0
Really, this seems to work.真的,这似乎有效。 Why?为什么?
0xff
is an int
constant (stricly speaking: an integer literal ) and has type int
. 0xff
是一个int
常量(严格来说:一个整数文字)并且具有int
类型。 Hence, the bit-wise And promotes (unsigned char)0xc0
to int
as well, yields the result of type int
, and hence, the std::ostream::operator<<
for int
is applied.因此,逐位并促进(unsigned char)0xc0
到int
为好,产生类型的结果int
,并且因此, std::ostream::operator<<
为int
被应用。
This is an option to solve this.这是解决这个问题的一个选项。 I can provide another one – just converting the unsigned char
to unsigned
.我可以提供另一个 - 只需将unsigned char
转换为unsigned
。
Where the promotion of unsigned char
to int
introduces a possible sign-bit extension (which is undesired in this case), this doesn't happen when unsigned char
is converted to unsigned
.将unsigned char
提升为int
引入了可能的符号位扩展(在这种情况下是不希望的),当unsigned char
转换为unsigned
时不会发生这种情况。 The output stream operator for unsigned
provides the intended output as well: unsigned
的输出流运算符也提供了预期的输出:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned)(unsigned char)0xc0 << '\n';
const unsigned char c = 0xc0;
std::cout << "Output of unsigned char c = 0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned)c << '\n';
return 0;
}
Output:输出:
Output of (unsigned char)0xc0: c0
Output of unsigned char c = 0xc0: c0
the C++20 way: C++20 方式:
unsigned char* data = new unsigned char[]{ "Hello world\n\t\r\0" };
std::size_t data_size = sizeof("Hello world\n\t\r\0") - 1;
auto sp = std::span(data, data_size );
std::transform( sp.begin(), sp.end(),
std::ostream_iterator<std::string>(std::cout),
[](unsigned char c) -> std::string {
return std::format("{:02X}", int(c));
});
or if you want to store result into string:或者如果要将结果存储到字符串中:
std::string result{};
result.reserve(size * 2 + 1);
std::transform( sp.begin(), sp.end(),
std::back_inserter(result),
[](unsigned char c) -> std::string {
return std::format("{:02X}", int(c));
});
Output:
48656C6C6F20776F726C640A090D00
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.