如何将十六进制字符串转换为 uint8_t 数组? (C语言)

问题描述

如何将十六进制字符串转换为 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,0x0C,0xDF,0x44,0x17,0x3B,0xE5,0x12,0xAF,0xFF,0xFE,0x11,0xDB,0xBA,0x1F,0x07,0x93,0x80,0x0E,0x13,0x2E,0xFC,0x7F,0x39,0xC1,0x0F,0x40};

感谢您的帮助!

解决方法

您可以使用 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,const char *src) {
    char buf[3];
    size_t i;
    int value;
    for (i = 0; i < count && *src; i++) {
        buf[0] = *src++;
        buf[1] = '\0';
        if (*src) {
            buf[1] = *src++;
            buf[2] = '\0';
        }
        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,const char *src) {
    char buf[3];
    size_t i;
    for (i = 0; i < count && *src; i++) {
        buf[0] = *src++;
        buf[1] = '\0';
        if (*src) {
            buf[1] = *src++;
            buf[2] = '\0';
        }
        if (sscanf(buf,"%hhx",&dest[i]) != 1)
            break;
    }
    return i;
}

纯粹主义者可能会争辩说,%hhx 需要一个指向 unsigned char 而不是 uint8_t 的指针,因此格式应该是 "%"SCNx8"%2"SCNx8,定义在 { {1}},但这些替代方案可读性较差且不必要,因为类型 <inttypes.h> 在定义它的架构上始终与类型 uint8_t 相同。

,

您需要了解的第一件事是十进制、十六进制甚至八进制就是存储在计算机内存中的二进制数字的显示方式。一旦将字节存储在数组中,它们就不再是真正的十六进制了。

现在如何解决您的问题:您需要一次提取两个字符,然后将每个字符转换为相应的整数值,并使用 bit-shirt 和 bit-or 将它们组合成一个字节值。

将数字 0 转换为 9 为它们对应的值很容易,因为 C 规范规定它们必须连续编码(即 '0' 必须紧接在 {{1} 之前} 等等)。这意味着您可以使用带有 '1' 的简单减法来获得数值('0''0' - '0' == 0 等)。

字母 '1' - '0' == 1A 更难通过,因为有许多不同的可能编码,包括一些不连续放置字母的编码。话虽如此,最常见的 ASCII 编码 do 就是这样做的,这意味着在大多数系统上,您可以使用与十进制数字相同的“技巧”。

那么如何组合,第一个值需要向上(向左)移动四位,然后与第二个值进行按位或运算。

结果应该是一个字节,其值与字符串中的两个十六进制数字相同。将此值附加到数组中。

,

class Store{
float array[]; 
public:
Store(float temp[]){
    std::cout<<"\n"<<sizeof(temp); //can't get sizeof 
    for(int i=0;i<9;i++){
        array[i]=temp[i];
    };
}
void showArrayContents(){
   for(int i=0;i<9;i++){
       std::cout<<array[i];
    }
 }
};

第一个字节是

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 }} 到 1'a'10,...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...