我怎样才能加快十六进制字符转换为二进制字符
How can i speed up hexadecimal characters conversion to binary characters
我已经有一个将十六进制字符(输入)转换为二进制字符(输出)的函数。对于少量数据(输入长度),它工作完美。但是当输入太大时,它 stuck/not 工作。可能是 strcat 花费了太多时间。有没有其他解决方案,所以我可以将大的十六进制输入字符转换为等效的二进制文件。
我的函数是:
void fun_hex_ch_2bin(int len_hex_str,uint8_t *hex,uint8_t *bin){
/* Extract first digit and find binary of each hex digit */
int i=0,j=0;
char array_hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
uint8_t *new_hex=malloc(len_hex_str*2);
char hex_char1,hex_char2;
j=0;
for(i=0;i<len_hex_str;i++)
{
hex_char1=array_hex[hex[i]&0x0f];
hex_char2=array_hex[(hex[i]>>4)&0x0f];
//printf("%c %c\n",hex_char1,hex_char2);
new_hex[j]=hex_char2;
new_hex[j+1]=hex_char1;
j=j+2;
}
for(i=0; i<len_hex_str*2; i++)
{
switch(new_hex[i])
{
case '0':
strcat(bin, "0000");
break;
case '1':
strcat(bin, "0001");
break;
case '2':
strcat(bin, "0010");
break;
case '3':
strcat(bin, "0011");
break;
case '4':
strcat(bin, "0100");
break;
case '5':
strcat(bin, "0101");
break;
case '6':
strcat(bin, "0110");
break;
case '7':
strcat(bin, "0111");
break;
case '8':
strcat(bin, "1000");
break;
case '9':
strcat(bin, "1001");
break;
case 'a':
case 'A':
strcat(bin, "1010");
break;
case 'b':
case 'B':
strcat(bin, "1011");
break;
case 'c':
case 'C':
strcat(bin, "1100");
break;
case 'd':
case 'D':
strcat(bin, "1101");
break;
case 'e':
case 'E':
strcat(bin, "1110");
break;
case 'f':
case 'F':
strcat(bin, "1111");
break;
default:
printf("Invalid hexadecimal input.");
}
}
}
16 是 2 的幂,因此将其转换为二进制非常简单。
每个十六进制数字恰好对应 4 个二进制数字 - 您可以相信这一事实。
作为第一步,您需要将输入字符从 ASCII 转换为数值。
如果字符在 '0'
和 '9'
之间,则一次传递输入十六进制字符串并减去 48 或如果字符在 'a'
和 'f'
之间减去 88(如果需要解释原因,请查看 ASCII table)。
之后转换就很简单了——遍历十六进制数组,对于每个十六进制值,查看最后一位并进行下一位恰好 4 次,移动到下一个十六进制值并重复该过程。
像这样:
int i = 0, j = 0;
while(i < len_hex_str)
{
bin[j++]=hex[i] & 1;
hex[i] >>= 1;
if(j % 4 == 0) i++;
}
并且由于您似乎需要它的 ASCII 表示形式,只需传递输出字符串并将每个数字加 48。
只需使用 sprintf()
而不是 strcat()
char *bin; // points to a long enough buffer
int binlen = 0;
binlen += sprintf(bin + binlen, "something"); // strcat(bin, "something");
binlen += sprintf(bin + binlen, "otherthing"); // strcat(bin, "otherthing");
binlen += sprintf(bin + binlen, "foobar"); // strcat(bin, "foobar");
//...
// you can even do
binlen += sprintf(bin + binlen, "%.2f", 2.71828); // strcat(bin, "2.72");
How can i speed up hexadecimal characters conversion to binary characters (?)
May be strcat take too much time.
是的。每次调用 strcat()
花费的时间越来越长,因为代码没有利用已经转换的数据。
strcat()
需要 n
时间遍历第一个字符。
1st strcat call, n = 0
2st strcat call, n = 8
3rd strcat call, n = 16
4th strcat call, n = 24
ith strcat call, n = 8*(i-1)
看看总和 (0+8+16+24+...) 如何随着 i
的增加而按 i*i
的顺序增加?
请注意,对 strcat(bin, ...)
的第一次调用是可疑的,因为 bin[0]
肯定不是空字符 - 连接到 字符串 时需要的东西。
Is there some alternate solution (?)
我建议重写。直接从 hex
读取为二进制并跳过中间转换为十六进制。
void fun_hex_ch_2bin(int len_hex_str, uint8_t *hex, uint8_t *bin) {
while (len_hex_str > 0) {
len_hex_str--;
// Start with the MSBit
for (uint8_t mask = 0x80; mask; mask >>=1) {
*bin++ = mask & *hex ? '1' : '0';
}
hex++;
}
// Append a null character as `bin` is to point to a _string_.
*bin = '[=11=]';
}
我希望 bin
,因为 string 是 char*
而不是 unit8_t *
.
我已经有一个将十六进制字符(输入)转换为二进制字符(输出)的函数。对于少量数据(输入长度),它工作完美。但是当输入太大时,它 stuck/not 工作。可能是 strcat 花费了太多时间。有没有其他解决方案,所以我可以将大的十六进制输入字符转换为等效的二进制文件。 我的函数是:
void fun_hex_ch_2bin(int len_hex_str,uint8_t *hex,uint8_t *bin){
/* Extract first digit and find binary of each hex digit */
int i=0,j=0;
char array_hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
uint8_t *new_hex=malloc(len_hex_str*2);
char hex_char1,hex_char2;
j=0;
for(i=0;i<len_hex_str;i++)
{
hex_char1=array_hex[hex[i]&0x0f];
hex_char2=array_hex[(hex[i]>>4)&0x0f];
//printf("%c %c\n",hex_char1,hex_char2);
new_hex[j]=hex_char2;
new_hex[j+1]=hex_char1;
j=j+2;
}
for(i=0; i<len_hex_str*2; i++)
{
switch(new_hex[i])
{
case '0':
strcat(bin, "0000");
break;
case '1':
strcat(bin, "0001");
break;
case '2':
strcat(bin, "0010");
break;
case '3':
strcat(bin, "0011");
break;
case '4':
strcat(bin, "0100");
break;
case '5':
strcat(bin, "0101");
break;
case '6':
strcat(bin, "0110");
break;
case '7':
strcat(bin, "0111");
break;
case '8':
strcat(bin, "1000");
break;
case '9':
strcat(bin, "1001");
break;
case 'a':
case 'A':
strcat(bin, "1010");
break;
case 'b':
case 'B':
strcat(bin, "1011");
break;
case 'c':
case 'C':
strcat(bin, "1100");
break;
case 'd':
case 'D':
strcat(bin, "1101");
break;
case 'e':
case 'E':
strcat(bin, "1110");
break;
case 'f':
case 'F':
strcat(bin, "1111");
break;
default:
printf("Invalid hexadecimal input.");
}
}
}
16 是 2 的幂,因此将其转换为二进制非常简单。
每个十六进制数字恰好对应 4 个二进制数字 - 您可以相信这一事实。
作为第一步,您需要将输入字符从 ASCII 转换为数值。
如果字符在 '0'
和 '9'
之间,则一次传递输入十六进制字符串并减去 48 或如果字符在 'a'
和 'f'
之间减去 88(如果需要解释原因,请查看 ASCII table)。
之后转换就很简单了——遍历十六进制数组,对于每个十六进制值,查看最后一位并进行下一位恰好 4 次,移动到下一个十六进制值并重复该过程。
像这样:
int i = 0, j = 0;
while(i < len_hex_str)
{
bin[j++]=hex[i] & 1;
hex[i] >>= 1;
if(j % 4 == 0) i++;
}
并且由于您似乎需要它的 ASCII 表示形式,只需传递输出字符串并将每个数字加 48。
只需使用 sprintf()
而不是 strcat()
char *bin; // points to a long enough buffer
int binlen = 0;
binlen += sprintf(bin + binlen, "something"); // strcat(bin, "something");
binlen += sprintf(bin + binlen, "otherthing"); // strcat(bin, "otherthing");
binlen += sprintf(bin + binlen, "foobar"); // strcat(bin, "foobar");
//...
// you can even do
binlen += sprintf(bin + binlen, "%.2f", 2.71828); // strcat(bin, "2.72");
How can i speed up hexadecimal characters conversion to binary characters (?)
May be strcat take too much time.
是的。每次调用 strcat()
花费的时间越来越长,因为代码没有利用已经转换的数据。
strcat()
需要 n
时间遍历第一个字符。
1st strcat call, n = 0
2st strcat call, n = 8
3rd strcat call, n = 16
4th strcat call, n = 24
ith strcat call, n = 8*(i-1)
看看总和 (0+8+16+24+...) 如何随着 i
的增加而按 i*i
的顺序增加?
请注意,对 strcat(bin, ...)
的第一次调用是可疑的,因为 bin[0]
肯定不是空字符 - 连接到 字符串 时需要的东西。
Is there some alternate solution (?)
我建议重写。直接从 hex
读取为二进制并跳过中间转换为十六进制。
void fun_hex_ch_2bin(int len_hex_str, uint8_t *hex, uint8_t *bin) {
while (len_hex_str > 0) {
len_hex_str--;
// Start with the MSBit
for (uint8_t mask = 0x80; mask; mask >>=1) {
*bin++ = mask & *hex ? '1' : '0';
}
hex++;
}
// Append a null character as `bin` is to point to a _string_.
*bin = '[=11=]';
}
我希望 bin
,因为 string 是 char*
而不是 unit8_t *
.