在一个字节中转换两个ASCIIhex字符(两个ASCII字节)
我想将两个ASCII字节转换为一个hex字节。 例如。
0x30 0x43 => 0x0C , 0x34 0x46 => 0x4F
…
ASCII字节是0
到9
之间的数字或A
和F
之间的字母(仅大写),因此在0x30
… 0x39
和0x41
… 0x46
我知道如何“构造” 0x4F
与数字0x34
和0x46 : 0x4F = 0x34 * 0x10 + 0x46
所以,实际上,我想以hex值转换一个ASCII字节。
为此,我可以构建和数组以将hex值分配给ASCII字符:
0x30 => 0x00 0x31 => 0x01 ... 0x46 => 0x0F
但是,也许它有一个最“正确”的解决方案。
该程序将在AVRμC上运行并使用avr-gcc
,因此scanf()
/ printf()
解决方案不适用。
你有个主意吗? 谢谢
我无法理解您的示例,但如果您想将包含hexascii字符的字符串转换为其字节值(例如,因此字符串“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);
res(必须至少是in
参数长度的一半)现在包含2个字节0x12,0x34
另请注意,此代码需要hex字母AF为大写,af不会执行(并且它不会执行任何错误检查 - 因此您必须将有效内容传递给它)。
您可以使用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]); }
任务:
将包含hexascii字符的字符串转换为其字节值,以便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。 第四步:转换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。 将包含hexascii字符的字符串转换为其字节值:
// 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
它的工作原理,但可以进行优化!
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; }