如何将十六进制字符串转换为 uint8_t 数组? (C语言)
How to convert a hex string to a uint8_t array? (C language)
如何将十六进制字符串转换为 uint8_t 数组?
我的字符串是 02012B1530A6E3958A98530031902003876940000000000CDF9844173BE512AFFFFFFE11DBBA1F00079387800E13012E11FC017FFFFFFFFE39C10F40
我想把它转换成这个数组:
uint8_t array_uint[] = {0x02, 0x01, 0x2B, 0x15, 0x30, 0xA6, 0xE3, 0x95, 0x8A, 0x98, 0x53, 0x00, 0x31, 0x90, 0x20, 0x03, 0x87, 0x69, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xDF, 0x98, 0x44, 0x17, 0x3B, 0xE5, 0x12, 0xAF, 0xFF, 0xFF, 0xFE, 0x11, 0xDB, 0xBA, 0x1F, 0x00, 0x07, 0x93, 0x87, 0x80, 0x0E, 0x13, 0x01, 0x2E, 0x11, 0xFC, 0x01, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x39, 0xC1, 0x0F, 0x40};
感谢您的帮助!
您需要了解的第一件事是十进制、十六进制甚至八进制正是存储在计算机内存中的 二进制 数字的表示方式。一旦将字节存储在数组中,它们就不再是真正的十六进制了。
现在解决你的问题:你需要一次提取两个字符,然后将每个字符转换为对应的整数值,并使用bit-shirt和bit-or将它们组合成一个字节值.
将数字 0
到 9
转换成相应的值很容易,因为 C 规范规定它们必须连续编码(即 '0'
必须紧接在 '1'
等等)。这意味着您可以使用 '0'
的简单减法来获取数值('0' - '0' == 0
、'1' - '0' == 1
等)。
字母 A
到 F
更难通过,因为有许多不同的可能编码,包括一些不连续放置字母的编码。话虽如此,最常见的编码 ASCII do 就是这样做的,这意味着在大多数系统上,您可以使用与十进制数字相同的“技巧”。
然后如何合并,第一个值需要向上(向左)移动四位,然后与第二个值按位或。
其结果应该是一个字节,其值与字符串中的两个十六进制数字相同。将此值附加到数组。
您可以使用 sscanf()
一次将 2 个字节从源字符串转换为目标数组:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
size_t i;
int value;
for (i = 0; i < count && sscanf(src + i * 2, "%2x", &value) == 1; i++) {
dest[i] = value;
}
return i;
}
但是请注意,在标准库为每次调用 sscanf()
计算源字符串长度的体系结构上,这种方法可能效率低下,具有二次时间复杂度。使用中间数组解决了这个问题:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
char buf[3];
size_t i;
int value;
for (i = 0; i < count && *src; i++) {
buf[0] = *src++;
buf[1] = '[=11=]';
if (*src) {
buf[1] = *src++;
buf[2] = '[=11=]';
}
if (sscanf(buf, "%x", &value) != 1)
break;
dest[i] = value;
}
return i;
}
将转换结果直接存入dest
数组很简单:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
char buf[3];
size_t i;
for (i = 0; i < count && *src; i++) {
buf[0] = *src++;
buf[1] = '[=12=]';
if (*src) {
buf[1] = *src++;
buf[2] = '[=12=]';
}
if (sscanf(buf, "%hhx", &dest[i]) != 1)
break;
}
return i;
}
纯粹主义者可能会争辩说 %hhx
需要一个指向 unsigned char
而不是 uint8_t
的指针,因此格式应该是 "%"SCNx8
或 "%2"SCNx8
,已定义在 <inttypes.h>
中,但这些替代方案的可读性较差且不必要,因为类型 uint8_t
在其定义的体系结构上始终与类型 unsigned char
相同。
有
char data[] = "02012B1530A6E3958A98530031902003876940000000000CDF9844173BE512AFFFFFFE11DBBA1F00079387800E13012E11FC017FFFFFFFFE39C10F40";
char *p = data;
第一个字节是
(hexdigit(p[0]) << 4) + hexdigit(p[1])
你可以用
循环上面的表达式
do {
uint8_t value = (hexdigit(p[0]) << 4) + hexdigit(p[1]);
p += 2;
} while (*p);
对于所有值(确保 data
具有偶数个字符)。
函数hexdigit()
(实现留作练习)将'0'
转换为0
,'1'
转换为1
,...,'a'
到 10
、'A'
到 10
、...
如何将十六进制字符串转换为 uint8_t 数组?
我的字符串是 02012B1530A6E3958A98530031902003876940000000000CDF9844173BE512AFFFFFFE11DBBA1F00079387800E13012E11FC017FFFFFFFFE39C10F40
我想把它转换成这个数组:
uint8_t array_uint[] = {0x02, 0x01, 0x2B, 0x15, 0x30, 0xA6, 0xE3, 0x95, 0x8A, 0x98, 0x53, 0x00, 0x31, 0x90, 0x20, 0x03, 0x87, 0x69, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xDF, 0x98, 0x44, 0x17, 0x3B, 0xE5, 0x12, 0xAF, 0xFF, 0xFF, 0xFE, 0x11, 0xDB, 0xBA, 0x1F, 0x00, 0x07, 0x93, 0x87, 0x80, 0x0E, 0x13, 0x01, 0x2E, 0x11, 0xFC, 0x01, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x39, 0xC1, 0x0F, 0x40};
感谢您的帮助!
您需要了解的第一件事是十进制、十六进制甚至八进制正是存储在计算机内存中的 二进制 数字的表示方式。一旦将字节存储在数组中,它们就不再是真正的十六进制了。
现在解决你的问题:你需要一次提取两个字符,然后将每个字符转换为对应的整数值,并使用bit-shirt和bit-or将它们组合成一个字节值.
将数字 0
到 9
转换成相应的值很容易,因为 C 规范规定它们必须连续编码(即 '0'
必须紧接在 '1'
等等)。这意味着您可以使用 '0'
的简单减法来获取数值('0' - '0' == 0
、'1' - '0' == 1
等)。
字母 A
到 F
更难通过,因为有许多不同的可能编码,包括一些不连续放置字母的编码。话虽如此,最常见的编码 ASCII do 就是这样做的,这意味着在大多数系统上,您可以使用与十进制数字相同的“技巧”。
然后如何合并,第一个值需要向上(向左)移动四位,然后与第二个值按位或。
其结果应该是一个字节,其值与字符串中的两个十六进制数字相同。将此值附加到数组。
您可以使用 sscanf()
一次将 2 个字节从源字符串转换为目标数组:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
size_t i;
int value;
for (i = 0; i < count && sscanf(src + i * 2, "%2x", &value) == 1; i++) {
dest[i] = value;
}
return i;
}
但是请注意,在标准库为每次调用 sscanf()
计算源字符串长度的体系结构上,这种方法可能效率低下,具有二次时间复杂度。使用中间数组解决了这个问题:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
char buf[3];
size_t i;
int value;
for (i = 0; i < count && *src; i++) {
buf[0] = *src++;
buf[1] = '[=11=]';
if (*src) {
buf[1] = *src++;
buf[2] = '[=11=]';
}
if (sscanf(buf, "%x", &value) != 1)
break;
dest[i] = value;
}
return i;
}
将转换结果直接存入dest
数组很简单:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
char buf[3];
size_t i;
for (i = 0; i < count && *src; i++) {
buf[0] = *src++;
buf[1] = '[=12=]';
if (*src) {
buf[1] = *src++;
buf[2] = '[=12=]';
}
if (sscanf(buf, "%hhx", &dest[i]) != 1)
break;
}
return i;
}
纯粹主义者可能会争辩说 %hhx
需要一个指向 unsigned char
而不是 uint8_t
的指针,因此格式应该是 "%"SCNx8
或 "%2"SCNx8
,已定义在 <inttypes.h>
中,但这些替代方案的可读性较差且不必要,因为类型 uint8_t
在其定义的体系结构上始终与类型 unsigned char
相同。
有
char data[] = "02012B1530A6E3958A98530031902003876940000000000CDF9844173BE512AFFFFFFE11DBBA1F00079387800E13012E11FC017FFFFFFFFE39C10F40";
char *p = data;
第一个字节是
(hexdigit(p[0]) << 4) + hexdigit(p[1])
你可以用
循环上面的表达式do {
uint8_t value = (hexdigit(p[0]) << 4) + hexdigit(p[1]);
p += 2;
} while (*p);
对于所有值(确保 data
具有偶数个字符)。
函数hexdigit()
(实现留作练习)将'0'
转换为0
,'1'
转换为1
,...,'a'
到 10
、'A'
到 10
、...