2011-08-03 52 views
2

我想將兩個ASCII字節轉換爲一個十六進制字節。 例如。在一個字節中轉換兩個ASCII十六進制字符(兩個ASCII字節)

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

的ASCII字節是09AF(僅上殼體)之間的字母之間的數,所以0x30 ... 0x390x41之間... 0x46

我知道如何「構建」 0x4F與數字0x340x46 : 0x4F = 0x34 * 0x10 + 0x46

所以,其實,我會轉換一個十六進制值的ASCII字節。

對於這一點,我可以建立和數組的十六進制值分配到的ASCII字符:

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

但是,也許它有一個最«正確»解決方案。

該方案將上AVRμC運行,並與avr-gcc編譯,所以scanf()/printf()解決方案是不合適的。

你有想法嗎? 感謝

+6

有沒有這樣的事情,如ASCII字節或十六進制字節。 –

+2

你(顯然!)想要做的是**將**一對字節轉換爲單個字節,**將兩個字節解釋爲ASCII碼元,後者又表示十六進制數字,併發出相應的十六進制值。解決這類問題需要精確理解你真正在做什麼;而精確的溝通也有很大的幫助:)你必須確定你從根本上理解了什麼是數據。就像大衛說的,字節只是字節;沒有ASCII字節或十六進制字節。 –

+0

ASCII字節=表示ASCII字符的字節,十六進制字節=用十六進制表示的字節。我知道字節只是字節;我只是不知道該如何解釋。但其他人理解我的意思。不是最重要的嗎? –

回答

10

我不能讓你的例子感,但如果你想轉換包含十六進制的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; 
} 

你會使用它像例如

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

與既判力(必須至少in參數長度的一半)現在包含2個字節0x12,0x34

還要注意的是這個代碼需要十六進制字母AF是資本,AF將不會做(並且它不會做任何錯誤檢查 - 所以你必須通過它有效的東西)。

+1

使用'(in [i] | 32) - 'a'+ 10'現在你可以支持大寫和小寫(只有一個更多的機器碼說明,很可能)。 –

+0

uint8_t是不是一個字節?如果應該包含兩個字節,它不應該是'uint16_t'嗎? –

+0

@Rudy Velthuis它應該是一個字節,因爲它包含1個字節,而不是2 – nos

6

您可以使用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]); 
} 
+0

好吧,這很容易... 我認爲4位左旋爲0到9之間的數字,但解決方案更簡單!謝謝 –

+0

在linux上你總是可以做* ascii *。 – whoplisp

+0

這是一個笑話? : $ man ascii Aucuneentréede manuel pour ascii –

0

任務:

轉換包含十六進制的ASCII字符到其字節的字符串值 所以ASCII "FF"變得0xFF和ASCII "10" (x31x30x00)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。Firt步:所以它僅包含上轉換的情況下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。將包含十六進制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×12 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 
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; 
} 
+0

直列uint8_t asciiToByte(炭C) { \t如果(C> = '0' &&ç<= '9') \t回覆C - '0'; \t if(c> ='A'&& c <='F') \t return c - 'A'+ 10; \t return 0; } – Dmitry

相關問題