[英]Hex_string to uint8_t msg[]
I want convert the characters in hex string 我想转换十六进制字符串中的字符
"0b7c28c9b7290c98d7438e70b3d3f7c848fbd7d1dc194ff83f4f7cc9b1378e98"
to uint8_t msg[]
and do not understand how to do it. 到
uint8_t msg[]
并且不知道该怎么做。
It seems simple, but have been unable to figure it out. 看起来很简单,但一直无法弄清楚。 I want to convert each character to a
uint8_t
hex value. 我想将每个字符转换为
uint8_t
十六进制值。 For example if I have 例如,如果我有
string result = "0123456789abcdef";
How do I convert the string to: 如何将字符串转换为:
uint8_t msg[] = "0123456789abcdef";
This func (thanks Converting a hex string to a byte array ) 此函数(感谢将十六进制字符串转换为字节数组 )
vector<uint8_t> HexToBytes(const string& hex) {
vector<uint8_t> bytes;
for (unsigned int i = 0; i < hex.length(); i += 2) {
string byteString = hex.substr(i, 2);
uint8_t byte = (uint8_t) strtol(byteString.c_str(), nullptr, 16);
bytes.push_back(byte);
}
return bytes;
}
using the above function we get the vector of bytes and call the method data() 使用上面的函数,我们获得字节向量,并调用方法data()
I want to thank the community now everything is working correctly. 我要感谢社区,现在一切正常。 Thanks for the comments, I was already desperate that I could not do such a simple thing.
感谢您的评论,我已经迫切希望做不到这么简单的事情。 Special thanks to @johnny-mopp
特别感谢@ johnny-mopp
Edit - Updated to ready bytes not characters 编辑-更新为就绪字节而不是字符
Rather than using .substr()
and calling C strtol
and casting to uint8_t
, you can simply use an istringstream
along with std::setbase(16)
to read the bytes as unsigned
values directly into your vector<uint8_t> msg
. .substr()
使用.substr()
并调用C strtol
并将其强制转换为uint8_t
,您只需将istringstream
与std::setbase(16)
一起使用, istringstream
将unsigned
值的字节直接读取到vector<uint8_t> msg
。 See std::setbase . 参见std :: setbase 。
For instance you can create an istringstream
from your string containing the hex characters, and then along with your vector of uint8_t
and a temporary unsigned
to read directly into before pushing back into your vector you could do, eg 例如,您可以从包含十六进制字符的字符串中创建一个
istringstream
,然后将其与uint8_t
的向量以及一个临时unsigned
向量一起直接读入,然后再压入向量即可,例如
std::string result ("0123456789abcdef"); /* input hex string */
std::string s2; /* string for 2-chars */
std::istringstream ss (result); /* stringstream of result */
std::vector<uint8_t> msg; /* vector of uint8_t */
while ((ss >> std::setw(2) >> s2)) { /* read 2-char at a time */
unsigned u; /* tmp unsigned value */
std::istringstream ss2 (s2); /* create 2-char stringstream */
ss2 >> std::setbase(16) >> u; /* convert hex to unsigned */
msg.push_back((uint8_t)u); /* add value as uint8_t */
}
In that way, each 2 characters in result
read using std::setw(2)
are used to create a 2-character stringstream that is then converted a an unsigned
value using std::setbase(16)
. 这样,使用
std::setw(2)
读取的result
每个2个字符将用于创建2个字符的字符串流,然后使用std::setbase(16)
将其转换为unsigned
值。 A complete example would be: 一个完整的例子是:
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
int main (void) {
std::string result ("0123456789abcdef"); /* input hex string */
std::string s2; /* string for 2-chars */
std::istringstream ss (result); /* stringstream of result */
std::vector<uint8_t> msg; /* vector of uint8_t */
while ((ss >> std::setw(2) >> s2)) { /* read 2-char at a time */
unsigned u; /* tmp unsigned value */
std::istringstream ss2 (s2); /* create 2-char stringstream */
ss2 >> std::setbase(16) >> u; /* convert hex to unsigned */
msg.push_back((uint8_t)u); /* add value as uint8_t */
}
std::cout << "string: " << result << "\nmsg: \n";
for (auto& h : msg) /* for each element of msg, output hex value */
std::cout << "\t" << std::setfill('0') << std::hex << std::setw(2)
<< (uint32_t)h << '\n';;
}
( note the cast required in the output to explicitly tell cout
to treat the uint8_t
value as an unsigned
value rather than a uint8_t
value which defaults to an character type by default. ( 请注意 ,输出中需要使用
cout
转换,以明确告知cout
将uint8_t
值视为unsigned
值,而不是默认为字符类型的uint8_t
值。
Example Use/Output 使用/输出示例
$ ./bin/hexstr2uint8_t
string: 0123456789abcdef
msg:
01
23
45
67
89
ab
cd
ef
( note there are 8 uint8_t
("byte") values stored this time instead of 16 character values) ( 请注意 ,这次存储了8个
uint8_t
(“字节”)值,而不是16个字符值)
It's just an alternative using the C++ iostream features which avoids the need to cast things around rather than calling strtol
directly (which in your case should probably be strtoul
to begin with). 这只是其中使用避免了需要转换的东西,而不是周围调用C ++的iostream功能替代
strtol
直接(在你的情况可能应该strtoul
开始与)。
Manual Hex Conversion 手动十六进制转换
In your last comment you indicate that using iostream and stringstream for the conversion is slow. 在最后一条评论中,您指出使用iostream和stringstream进行转换很慢。 You can attempt to optimize a bit by eliminating the stringstream and using a
string::iterator
to step through the string manually converting each character and forming each uint8_t
byte as you go (protecting against a final nibble or 1/2-byte), eg 您可以尝试通过消除
string::iterator
并使用string::iterator
来逐步优化字符串,以手动转换每个字符并uint8_t
形成每个uint8_t
字节(以防止出现最后的半字节或1/2字节),例如
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
/* simple manual conversion of hexchar to value */
uint8_t c2hex (const char c)
{
uint8_t u = 0;
if ('0' <= c && c <= '9')
u = c - '0';
else if ('a' <= c && c <= 'f')
u = c - 'W';
else if ('A' <= c && c <= 'F')
u = c - '7';
else
std::cerr << "error: invalid hex char '" << c << "'\n";
return u;
}
int main (void) {
std::string s ("0123456789abcdef");
std::vector<uint8_t> msg;
for (std::string::iterator n = s.begin(); n != s.end(); n += 2) {
uint8_t u = c2hex (*n); /* save high-nibble */
if (n + 1 != s.end()) /* if low-nibble available */
u = (u << 4) | c2hex (n[1]); /* shift high left 4 & or */
msg.push_back(u); /* store byte in msg */
}
std::cout << "string: " << s << "\nmsg:\n";
for (auto& h : msg)
std::cout << "\t" << std::setfill('0') << std::hex
<< std::setw(2) << (unsigned)h << '\n';
}
(output is the same as above) (输出与上面相同)
If you can guarantee there will always be an even number of characters in your string (bytes only and no 1/2-byte as the final-odd character), you can further optimize by removing the conditional and simply using: 如果可以保证字符串中始终有偶数个字符(仅字节,最后一个奇数字符不为1/2字节),则可以通过删除条件并简单地使用以下命令来进一步优化:
uint8_t u = c2hex (n[1]) | (c2hex (*n) << 4);
Make sure you are compiling with full optimization, eg -O3
(or -Ofast
gcc version >= 4.6) on gcc/clang and /Ox
with VS. 请确保您有充分优化的编译,如
-O3
(或-Ofast
上的gcc /铛gcc版本> = 4.6)和/Ox
与VS.
Give that a try and compare performance, you can additionally dump the differing versions to assembly and see if there are any additional hints there. 尝试比较性能,您还可以将不同的版本转储到汇编中,看看那里是否还有其他提示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.