在一个字节中转换两个ASCII十六进制字符(两个ASCII字节)

Loï*_* G. 3 c hex ascii avr-gcc

我想将两个ASCII字节转换为一个十六进制字节.例如.

0x30 0x43 => 0x0C , 0x34 0x46 => 0x4F ...

ASCII字节是介于09之间的数字AF(和大写字母之间)之间的字母,所以介于0x30...... 0x390x41... 之间0x46

我知道如何0x4F用数字0x34和"构建"0x46 : 0x4F = 0x34 * 0x10 + 0x46

所以,实际上,我想以十六进制值转换一个ASCII字节.

为此,我可以构建和数组以将十六进制值分配给ASCII字符:

0x30 => 0x00
0x31 => 0x01
...
0x46 => 0x0F
Run Code Online (Sandbox Code Playgroud)

但是,也许它有一个最"适当"的解决方案.

该程序将在AVRμC上运行并使用avr-gcc,因此scanf()/ printf()解决方案不适用.

你有个主意吗?谢谢

nos*_*nos 11

我无法理解您的示例,但如果您想将包含十六进制ascii字符的字符串转换为其字节值(例如,因此字符串"56"变为字节0x56,您可以使用此(假设您的系统正在使用) ASCII)

uint8_t*
hex_decode(const char *in, size_t len,uint8_t *out)
{
        unsigned int i, t, hn, ln;

        for (t = 0,i = 0; i < len; i+=2,++t) {

                hn = in[i] > '9' ? in[i] - 'A' + 10 : in[i] - '0';
                ln = in[i+1] > '9' ? in[i+1] - 'A' + 10 : in[i+1] - '0';

                out[t] = (hn << 4 ) | ln;
        }

        return out;
}
Run Code Online (Sandbox Code Playgroud)

你会像使用它一样使用它

char x[]="1234";
uint8_t res[2];
hex_decode(x,strlen(x),res);
Run Code Online (Sandbox Code Playgroud)

res(必须至少是in参数长度的一半)现在包含2个字节0x12,0x34

另请注意,此代码需要十六进制字母AF为大写,af不会执行(并且它不会执行任何错误检查 - 因此您必须传递有效的东西).


Car*_*rum 7

您可以使用strtol(),这是avr-libc的一部分,或者您可以非常轻松地编写您的特定案例:

unsigned char charToHexDigit(char c)
{
  if (c >= 'A')
    return c - 'A' + 10;
  else
    return c - '0';
}

unsigned char stringToByte(char c[2])
{
  return charToHexDigit(c[0]) * 16 + charToHexDigit(c[1]);
}
Run Code Online (Sandbox Code Playgroud)