3

2 つの ASCII バイトを 1 つの 16 進数バイトに変換したいと考えています。例えば。

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

ASCII バイトは、 と の間の数字09または と の間の文字A(F大文字のみ)、つまり0x30...0x390x41...の間です。0x46

0x4F数字0x34を使って「構築」する方法を知っている0x46 : 0x4F = 0x34 * 0x10 + 0x46

したがって、実際には、1 ASCII バイトを 16 進数値に変換します。

そのために、16 進値を ASCII char に割り当てるように構築して配列することができます。

0x30 => 0x00
0x31 => 0x01
...
0x46 => 0x0F

しかし、おそらくそれは最も「適切な」解決策を持っています。

このプログラムは AVR µC で実行され、 でコンパイルされるavr-gccため、scanf()/printf()ソリューションは適していません。

アイデアはありますか?ありがとう

4

6 に答える 6

11

私はあなたの例を理解することはできませんが、16 進数の ASCII 文字を含む文字列をそのバイト値に変換したい場合 (たとえば、文字列 "56" がバイト 0x56 になるようにするには、これを使用できます (システムがアスキー)

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;
}

たとえば、次のように使用します

char x[]="1234";
uint8_t res[2];
hex_decode(x,strlen(x),res);

res (パラメータの長さの少なくとも半分である必要がありinます) には、2 バイトの 0x12,0x34 が含まれています。

また、このコードでは 16 進数の文字 AF を大文字にする必要がありますが、af は使用できません (また、エラー チェックを行わないため、有効なものを渡す必要があります)。

于 2011-08-03T20:47:57.980 に答える
8

avr-libcstrtol()の一部である を使用するか、特定のケースだけを非常に簡単に作成できます。

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]);
}
于 2011-08-03T20:45:47.060 に答える
0

タスク:

"FF"ascii が asciiになり0xFF、ascii"10" (x31x30x00)がなるように、16 進数の ascii 文字を含む文字列をそのバイト値に変換します0x10

char asciiString[]="aaAA12fF";// input ascii hex string 
char result[4];               // byte equivalent of the asciiString (the size should be at half of asciiString[])

// 最終結果は次のようになります。

result[0] = 0xAA;
result[1] = 0xAA;       
result[2] = 0x12;
result[3] = 0xFF;

//1. 最初のステップ: asciiString を変換して、大文字のみが含まれるようにします。

// convert string to upper cases:
stringToUpperCases(asciiString);

使用する:

void stringToUpperCases(char *p)
{   
    for(int i=0; *(p+i) !='\0'; i++)
    {
        *(p+i) = (unsigned char) toupper( *(p+i) );
    }
}

//2. 16 進数の ASCII 文字を含む文字列をそのバイト値に変換します。

// convert string to bytes:

int nrOfBytes = stringToBytes(asciiString,result);

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

unsigned char ascii2HexToByte(char *ptr)
{
    return charToHexDigit( *ptr )*16 + charToHexDigit( *(ptr+1) );
}

int stringToBytes(char *string, char *result)
{
    int k=0;
    int strLen = strlen(string);

    for(int i = 0; i < strLen; i = i + 2)
    {
        result[k] = ascii2HexToByte( &string[i] );
        k++;
    }

    return k; // number of bytes in the result array 
}   

//3. 印刷結果:

printNrOfBytes(nrOfBytes, result);

// 使用する:

void printNrOfBytes(int nr, char *p)
{
   for(int i= 0; i < nr; i++)
    {
        printf( "0x%02X ", (unsigned char)*(p+i) );
    }
    printf( "\n");
}

//4. 結果は次のようになります。

0xAA 0xAA 0x12 0xFF

//5. これはテストプログラムです:

char asciiString[]="aaAA12fF"; // input ascii hex string 
char result[4];                // result  
// convert string to upper cases:
stringToUpperCases(asciiString);

// convert string to bytes
int nrOfBytes = stringToBytes(asciiString,result);

// print result:
printNrOfBytes(nrOfBytes, result);

// result:
//  0xAA 0xAA 0x12 0xFF
于 2013-01-02T18:48:48.040 に答える
0

それは動作しますが、より最適化される可能性があります!

inline uint8_t  twoAsciiByteToByte(const std::string& s)
{
    uint8_t r = 0;

    if (s.length() == 4)
    {
        uint8_t a = asciiToByte(s[0]);
        uint8_t b = asciiToByte(s[1]);
        uint8_t c = asciiToByte(s[2]);
        uint8_t d = asciiToByte(s[3]);

        int h = (a * 10 + b);
        int l = (c * 10 + d);

        if (s[0] == '3')
            h -= 30;
        else if (s[0] == '4')
            h -= 31;

        if (s[2] == '3')
            l -= 30;
        else if (s[2] == '4')
            l -= 31;

        r = (h << 4) | l;
    }

    return r;
}
于 2015-04-15T15:52:16.653 に答える