如何将十六进制字符串转换成C中的二进制字符串?

时间:2022-02-06 18:22:25

I have a text file with hexadecimal values. Now I need to convert the hexadecimal value to binary and need to save it on another file. But I don't know how to convert the hexadecimal value to a binary string! Please help...

我有一个十六进制值的文本文件。现在我需要将十六进制值转换为二进制,并需要将它保存到另一个文件中。但是我不知道如何将十六进制值转换成二进制字符串!请帮助……

8 个解决方案

#1


2  

const char input[] = "..."; // the value to be converted
char res[9]; // the length of the output string has to be n+1 where n is the number of binary digits to show, in this case 8
res[8] = '\0';
int t = 128; // set this to s^(n-1) where n is the number of binary digits to show, in this case 8
int v = strtol(input, 0, 16); // convert the hex value to a number

while(t) // loop till we're done
{
    strcat(res, t < v ? "1" : "0");
    if(t < v)
        v -= t;
    t /= 2;
}
// res now contains the binary representation of the number

As an alternative (this assumes there's no prefix like in "0x3A"):

作为替代方案(假设“0x3A”中没有前缀):

const char binary[16][5] = {"0000", "0001", "0010", "0011", "0100", ...};
const char digits = "0123456789abcdef";

const char input[] = "..." // input value
char res[1024];
res[0] = '\0';
int p = 0;

while(input[p])
{
    const char *v = strchr(digits, tolower(input[p++]));
    if (v)
        strcat(res, binary[v - digits]);
}
// res now contains the binary representation of the number

#2


9  

It's quite easy, really, because the translation goes digit-by-digit.

这很简单,因为翻译是按数字进行的。

0 - 0000
1 - 0001
2 - 0010
3 - 0011
4 - 0100
5 - 0101
6 - 0110
7 - 0111
8 - 1000
9 - 1001
A - 1010
B - 1011
C - 1100
D - 1101
E - 1110
F - 1111

So, for example, the hex number FE2F8 will be 11111110001011111000 in binary

例如,十六进制数FE2F8在二进制中是11111111100010111000

#3


1  

There are many ways to solve this question that use some arithmetics to convert from ascii character ranges 0-9 and a-f (or A-F) to binary. I wanted to find a solution which only uses a lookup table and benchmark that against a solution that uses arithmetics instead. Strangly enough, none of the answers above implement a purely arithmetic solution and some answers even assume that "converting to binary" means converting to a ascii string of characters "0" and "1".

有许多方法可以解决这个问题,它们使用一些算术方法将ascii字符范围从0-9和a-f(或a-f)转换为二进制。我想找到一个只使用查找表的解决方案,并将其与使用算术方法的解决方案进行比较。奇怪的是,上面的所有答案都没有实现一个纯粹的算术解决方案,有些答案甚至假设“转换为二进制”意味着转换为由字符“0”和“1”组成的ascii字符串。

Lets first do some setups. Firstly, we want to have the whole test data in memory so that we avoid disk I/O influencing the test. Here is how I create a header with a character array "testdata" of 104857600 bytes, roughly 105 MB. As the question was how to convert files, our implementation should be fast on large data.

让我们先做一些设置。首先,我们希望将整个测试数据保存在内存中,以避免磁盘I/O影响测试。下面是我如何创建一个包含104857600字节的字符数组“testdata”的头,大约105mb。

$ { printf "char *testdata =\""; cat /dev/urandom \
    | tr -d -c "0123456789abcdefABCDEF" \
    | dd count=100 iflag=fullblock bs=1M; printf "\";\n" } > testdata.h

Next, we create the lookup tables. I see two possible ways to solve this with a lookup table. Either the lookup table maps individual ascii hex characters to half bytes or it maps two hex characters to a full byte. In the former case, the lookup table has to have 256 entries. In the latter case, the lookup table has to have 256*256=65536 entries. We can reduce the size of the latter by realizing that the first bit of the first byte will never be used. So we only need a lookup table of 128*256=32768 entries. Since that solution also requires an additional calculation step (applying a bitmask) we will benchmark both. We end up with the following test cases:

接下来,我们创建查找表。我看到了用查找表解决这个问题的两种可能的方法。查找表要么将单个ascii十六进制字符映射为半字节,要么将两个十六进制字符映射为一个完整字节。在前一种情况下,查找表必须有256个条目。在后一种情况下,查找表必须有256*256=65536个条目。我们可以通过意识到第一个字节的第一个字节永远不会被使用来减少后者的大小。因此,我们只需要一个128*256=32768个条目的查找表。由于该解决方案还需要额外的计算步骤(应用位掩码),我们将对两者进行基准测试。我们最终得到以下测试用例:

  1. arithmetic solution
  2. 算法的解决方案
  3. 256 entries lookup table
  4. 256个条目查找表
  5. 32768 entries lookup table
  6. 32768个条目查找表
  7. 65536 entries lookup table
  8. 65536个条目查找表

The first lookup table is easy to generate using some python:

第一个查找表很容易使用一些python生成:

#!/usr/bin/env python

import sys,struct

sys.stdout.write("unsigned char base16_decoding_table1[256] = {\n")

for i in xrange(256):
    try:
        j = str(int(chr(i), 16))
    except:
        j = '0'
    sys.stdout.write(j+',')
sys.stdout.write("};\n")

sys.stdout.write("\n")

l = 128*256*["0"]

for a in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']:
    for b in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']:
        l[struct.unpack("<H", a+b)[0]] = str(int(a+b, 16))

line = "unsigned char base16_decoding_table2[%d] = {"%(128*256)

for e in l:
    line += e+","
    if len(line) > 70:
        sys.stdout.write(line+"\n")
        line = ""
sys.stdout.write(line+"};\n")

sys.stdout.write("\n")

l = 256*256*["0"]

for a in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']:
    for b in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']:
        l[struct.unpack("<H", a+b)[0]] = str(int(a+b, 16))

line = "unsigned char base16_decoding_table3[%d] = {"%(256*256)

for e in l:
    line += e+","
    if len(line) > 70:
        sys.stdout.write(line+"\n")
        line = ""
sys.stdout.write(line+"};\n")

And then:

然后:

python gen.py > base16_decoding_table.h

Now we can write some C code to test.

现在我们可以编写一些C代码进行测试。

#include <stdio.h>
#include <time.h>
#include <inttypes.h>

#include "testdata.h"
#include "base16_decoding_table.h"

#define TESTDATALEN 104857600

/* the resulting binary string is half the size of the input hex string
 * because every two hex characters map to one byte */
unsigned char result[TESTDATALEN/2];

void test1()
{
    size_t i;
    char cur;
    unsigned char val;
    for (i = 0; i < TESTDATALEN; i++) {
        cur = testdata[i];
        if (cur >= 97) {
            val = cur - 97 + 10;
        } else if (cur >= 65) {
            val = cur - 65 + 10;
        } else {
            val = cur - 48;
        }
        /* even characters are the first half, odd characters the second half
         * of the current output byte */
        if (i%2 == 0) {
            result[i/2] = val << 4;
        } else {
            result[i/2] |= val;
        }
    }
}

void test2()
{
    size_t i;
    char cur;
    unsigned char val;
    for (i = 0; i < TESTDATALEN; i++) {
        cur = testdata[i];
        val = base16_decoding_table1[(int)cur];
        /* even characters are the first half, odd characters the second half
         * of the current output byte */
        if (i%2 == 0) {
            result[i/2] = val << 4;
        } else {
            result[i/2] |= val;
        }
    }
}

void test3()
{
    size_t i;
    uint16_t *cur;
    unsigned char val;
    for (i = 0; i < TESTDATALEN; i+=2) {
        cur = (uint16_t*)(testdata+i);
        // apply bitmask to make sure that the first bit is zero
        val = base16_decoding_table2[*cur & 0x7fff];
        result[i/2] = val;
    }
}

void test4()
{
    size_t i;
    uint16_t *cur;
    unsigned char val;
    for (i = 0; i < TESTDATALEN; i+=2) {
        cur = (uint16_t*)(testdata+i);
        val = base16_decoding_table3[*cur];
        result[i/2] = val;
    }
}

#define NUMTESTS 1000

int main() {
    struct timespec before, after;
    unsigned long long checksum;
    int i;
    double elapsed;

    clock_gettime(CLOCK_MONOTONIC, &before);
    for (i = 0; i < NUMTESTS; i++) {
        test1();
    }
    clock_gettime(CLOCK_MONOTONIC, &after);

    checksum = 0;
    for (i = 0; i < TESTDATALEN/2; i++) {
        checksum += result[i];
    }
    printf("checksum: %llu\n", checksum);
    elapsed = difftime(after.tv_sec, before.tv_sec) + (after.tv_nsec - before.tv_nsec)/1.0e9;
    printf("arithmetic solution took %f seconds\n", elapsed);

    clock_gettime(CLOCK_MONOTONIC, &before);
    for (i = 0; i < NUMTESTS; i++) {
        test2();
    }
    clock_gettime(CLOCK_MONOTONIC, &after);

    checksum = 0;
    for (i = 0; i < TESTDATALEN/2; i++) {
        checksum += result[i];
    }
    printf("checksum: %llu\n", checksum);
    elapsed = difftime(after.tv_sec, before.tv_sec) + (after.tv_nsec - before.tv_nsec)/1.0e9;
    printf("256 entries table took %f seconds\n", elapsed);

    clock_gettime(CLOCK_MONOTONIC, &before);
    for (i = 0; i < NUMTESTS; i++) {
        test3();
    }
    clock_gettime(CLOCK_MONOTONIC, &after);

    checksum = 0;
    for (i = 0; i < TESTDATALEN/2; i++) {
        checksum += result[i];
    }
    printf("checksum: %llu\n", checksum);
    elapsed = difftime(after.tv_sec, before.tv_sec) + (after.tv_nsec - before.tv_nsec)/1.0e9;
    printf("32768 entries table took %f seconds\n", elapsed);

    clock_gettime(CLOCK_MONOTONIC, &before);
    for (i = 0; i < NUMTESTS; i++) {
        test4();
    }
    clock_gettime(CLOCK_MONOTONIC, &after);

    checksum = 0;
    for (i = 0; i < TESTDATALEN/2; i++) {
        checksum += result[i];
    }
    printf("checksum: %llu\n", checksum);
    elapsed = difftime(after.tv_sec, before.tv_sec) + (after.tv_nsec - before.tv_nsec)/1.0e9;
    printf("65536 entries table took %f seconds\n", elapsed);

    return 0;
}

Lets compile the thing:

允许编译:

$ gcc -O3 -g -Wall -Wextra test.c

And run it:

并运行:

$ ./a.out

The result:

结果:

  1. arithmetic solution: 437.17 s
  2. 算法解决方案:437.17秒
  3. 256 entries lookup table: 117.80 s
  4. 查询表:117.80 s。
  5. 32768 entries lookup table: 52.33 s
  6. 32768项查找表:52.33秒
  7. 65536 entries lookup table: 44.66 s
  8. 查询表:44.66秒

This we can conclude lookup tables beat arithmetic solutions any time and that wasting memory for bigger lookup tables might be worth the additional runtime.

我们可以得出这样的结论:查找表在任何时候都优于算术解决方案,为更大的查找表浪费内存可能值得额外的运行时。

#4


0  

void hex_binary(char * res){
char binary[16][5] = {"0000", "0001", "0010", "0011", "0100", "0101","0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110","1111"};
char digits [] = "0123456789abcdef";

const char input[] = "a9e6"; // input value
res[0] = '\0';
int p = 0;
int value =0;
    while(input[p])
    {
        const char *v = strchr(digits, tolower(input[p]));
        if(v[0]>96){
            value=v[0]-87;
        }
        else{
            value=v[0]-48;
        }
        if (v){
            strcat(res, binary[value]);
        }
        p++;
    }
    printf("Res:%s\n", res);
}

#5


-1  

void printBin(unsigned int num){
  char str[sizeof(num)*8];
  char *p = str;
  for(*p='0'; num; num/=2) { *p++='0'+num%2; } //store remainders
  for(--p; p>=str; putchar(*p--)) {;}          //print remainders in reverse
  putchar('\n');
}

#6


-2  

The quickest and easiest way is to read the hex file and, for each character ('0' through 'F') read, do a table lookup of the equivalent (0 through 15) binary value. There are, as ever, more elegant ways but this is very straightforward, maybe something like:

最快、最简单的方法是读取十六进制文件,对于读取的每个字符('0'到'F'),执行等价的(0到15)二进制值的表查找。和以往一样,也有更优雅的方式,但这是非常直接的,可能是这样的:

switch (charval) {
  case '0': binval = 0;
  case '1': binval = 1;
  case '2': binval = 2;
  case '3': binval = 3;
   ....
  case 'a': binval = 10;
  case 'b': binval = 11;
  case 'A': binval = 10;
  case 'B': binval = 11;
  ....
  case 'f':  binval = 15;
  case 'F':  binval = 15;
  default:   binval = -1;  // error case
}

Now you have to use shifts and IORs/ADDs to construct words of the size you want from these individual 4-bit binary values.

现在,您必须使用移位和ior / add来构造您想从这些单独的4位二进制值中获得的大小的字。

#7


-3  

That's my function to convert HEX to BIN, byte a byte.

这是我把十六进制转换成二进制的函数,一个字节。

void HexToBin(char hex_number, char* bit_number) {
    int max = 128;
    for(int i = 7 ; i >-1 ; i--){
        bit_number [i] = (hex_number & max ) ? 1 : 0;
        max >>=1;
    }
}

and the call to the function:

对函数的调用:

void main (void){

    char hex_number = 0x6E; //0110 1110
    char bit_number[8]={0,0,0,0,0,0,0,0};
    HexToBin(hex_number,bit_number);

    for(int i = 7 ; i >-1 ; i--)
        printf("%d",bit_number[i]);

    printf("\n");
    system("pause");
}

And here is the MSDOS answer:

下面是MSDOS的回答:

01101110

Press a key to continue . . .

Quite easy!

很简单!

#8


-3  

#include <stdio.h>

int main()
{
    long int binaryNumber,
             hexadecimalNumber = 0,
             j = 1,
             remainder;

    printf("Enter any number any binary number: ");
    scanf("%ld", &binaryNumber);

    while(binaryNumber != 0) {
        remainder = binaryNumber % 10;
        hexadecimalNumber = hexadecimalNumber + remainder * j;
        j = j * 2;
        binaryNumber = binaryNumber / 10;
    }
    printf("Equivalent hexadecimal value: %X", hexadecimalNumber);
    return 0;
}

#1


2  

const char input[] = "..."; // the value to be converted
char res[9]; // the length of the output string has to be n+1 where n is the number of binary digits to show, in this case 8
res[8] = '\0';
int t = 128; // set this to s^(n-1) where n is the number of binary digits to show, in this case 8
int v = strtol(input, 0, 16); // convert the hex value to a number

while(t) // loop till we're done
{
    strcat(res, t < v ? "1" : "0");
    if(t < v)
        v -= t;
    t /= 2;
}
// res now contains the binary representation of the number

As an alternative (this assumes there's no prefix like in "0x3A"):

作为替代方案(假设“0x3A”中没有前缀):

const char binary[16][5] = {"0000", "0001", "0010", "0011", "0100", ...};
const char digits = "0123456789abcdef";

const char input[] = "..." // input value
char res[1024];
res[0] = '\0';
int p = 0;

while(input[p])
{
    const char *v = strchr(digits, tolower(input[p++]));
    if (v)
        strcat(res, binary[v - digits]);
}
// res now contains the binary representation of the number

#2


9  

It's quite easy, really, because the translation goes digit-by-digit.

这很简单,因为翻译是按数字进行的。

0 - 0000
1 - 0001
2 - 0010
3 - 0011
4 - 0100
5 - 0101
6 - 0110
7 - 0111
8 - 1000
9 - 1001
A - 1010
B - 1011
C - 1100
D - 1101
E - 1110
F - 1111

So, for example, the hex number FE2F8 will be 11111110001011111000 in binary

例如,十六进制数FE2F8在二进制中是11111111100010111000

#3


1  

There are many ways to solve this question that use some arithmetics to convert from ascii character ranges 0-9 and a-f (or A-F) to binary. I wanted to find a solution which only uses a lookup table and benchmark that against a solution that uses arithmetics instead. Strangly enough, none of the answers above implement a purely arithmetic solution and some answers even assume that "converting to binary" means converting to a ascii string of characters "0" and "1".

有许多方法可以解决这个问题,它们使用一些算术方法将ascii字符范围从0-9和a-f(或a-f)转换为二进制。我想找到一个只使用查找表的解决方案,并将其与使用算术方法的解决方案进行比较。奇怪的是,上面的所有答案都没有实现一个纯粹的算术解决方案,有些答案甚至假设“转换为二进制”意味着转换为由字符“0”和“1”组成的ascii字符串。

Lets first do some setups. Firstly, we want to have the whole test data in memory so that we avoid disk I/O influencing the test. Here is how I create a header with a character array "testdata" of 104857600 bytes, roughly 105 MB. As the question was how to convert files, our implementation should be fast on large data.

让我们先做一些设置。首先,我们希望将整个测试数据保存在内存中,以避免磁盘I/O影响测试。下面是我如何创建一个包含104857600字节的字符数组“testdata”的头,大约105mb。

$ { printf "char *testdata =\""; cat /dev/urandom \
    | tr -d -c "0123456789abcdefABCDEF" \
    | dd count=100 iflag=fullblock bs=1M; printf "\";\n" } > testdata.h

Next, we create the lookup tables. I see two possible ways to solve this with a lookup table. Either the lookup table maps individual ascii hex characters to half bytes or it maps two hex characters to a full byte. In the former case, the lookup table has to have 256 entries. In the latter case, the lookup table has to have 256*256=65536 entries. We can reduce the size of the latter by realizing that the first bit of the first byte will never be used. So we only need a lookup table of 128*256=32768 entries. Since that solution also requires an additional calculation step (applying a bitmask) we will benchmark both. We end up with the following test cases:

接下来,我们创建查找表。我看到了用查找表解决这个问题的两种可能的方法。查找表要么将单个ascii十六进制字符映射为半字节,要么将两个十六进制字符映射为一个完整字节。在前一种情况下,查找表必须有256个条目。在后一种情况下,查找表必须有256*256=65536个条目。我们可以通过意识到第一个字节的第一个字节永远不会被使用来减少后者的大小。因此,我们只需要一个128*256=32768个条目的查找表。由于该解决方案还需要额外的计算步骤(应用位掩码),我们将对两者进行基准测试。我们最终得到以下测试用例:

  1. arithmetic solution
  2. 算法的解决方案
  3. 256 entries lookup table
  4. 256个条目查找表
  5. 32768 entries lookup table
  6. 32768个条目查找表
  7. 65536 entries lookup table
  8. 65536个条目查找表

The first lookup table is easy to generate using some python:

第一个查找表很容易使用一些python生成:

#!/usr/bin/env python

import sys,struct

sys.stdout.write("unsigned char base16_decoding_table1[256] = {\n")

for i in xrange(256):
    try:
        j = str(int(chr(i), 16))
    except:
        j = '0'
    sys.stdout.write(j+',')
sys.stdout.write("};\n")

sys.stdout.write("\n")

l = 128*256*["0"]

for a in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']:
    for b in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']:
        l[struct.unpack("<H", a+b)[0]] = str(int(a+b, 16))

line = "unsigned char base16_decoding_table2[%d] = {"%(128*256)

for e in l:
    line += e+","
    if len(line) > 70:
        sys.stdout.write(line+"\n")
        line = ""
sys.stdout.write(line+"};\n")

sys.stdout.write("\n")

l = 256*256*["0"]

for a in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']:
    for b in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']:
        l[struct.unpack("<H", a+b)[0]] = str(int(a+b, 16))

line = "unsigned char base16_decoding_table3[%d] = {"%(256*256)

for e in l:
    line += e+","
    if len(line) > 70:
        sys.stdout.write(line+"\n")
        line = ""
sys.stdout.write(line+"};\n")

And then:

然后:

python gen.py > base16_decoding_table.h

Now we can write some C code to test.

现在我们可以编写一些C代码进行测试。

#include <stdio.h>
#include <time.h>
#include <inttypes.h>

#include "testdata.h"
#include "base16_decoding_table.h"

#define TESTDATALEN 104857600

/* the resulting binary string is half the size of the input hex string
 * because every two hex characters map to one byte */
unsigned char result[TESTDATALEN/2];

void test1()
{
    size_t i;
    char cur;
    unsigned char val;
    for (i = 0; i < TESTDATALEN; i++) {
        cur = testdata[i];
        if (cur >= 97) {
            val = cur - 97 + 10;
        } else if (cur >= 65) {
            val = cur - 65 + 10;
        } else {
            val = cur - 48;
        }
        /* even characters are the first half, odd characters the second half
         * of the current output byte */
        if (i%2 == 0) {
            result[i/2] = val << 4;
        } else {
            result[i/2] |= val;
        }
    }
}

void test2()
{
    size_t i;
    char cur;
    unsigned char val;
    for (i = 0; i < TESTDATALEN; i++) {
        cur = testdata[i];
        val = base16_decoding_table1[(int)cur];
        /* even characters are the first half, odd characters the second half
         * of the current output byte */
        if (i%2 == 0) {
            result[i/2] = val << 4;
        } else {
            result[i/2] |= val;
        }
    }
}

void test3()
{
    size_t i;
    uint16_t *cur;
    unsigned char val;
    for (i = 0; i < TESTDATALEN; i+=2) {
        cur = (uint16_t*)(testdata+i);
        // apply bitmask to make sure that the first bit is zero
        val = base16_decoding_table2[*cur & 0x7fff];
        result[i/2] = val;
    }
}

void test4()
{
    size_t i;
    uint16_t *cur;
    unsigned char val;
    for (i = 0; i < TESTDATALEN; i+=2) {
        cur = (uint16_t*)(testdata+i);
        val = base16_decoding_table3[*cur];
        result[i/2] = val;
    }
}

#define NUMTESTS 1000

int main() {
    struct timespec before, after;
    unsigned long long checksum;
    int i;
    double elapsed;

    clock_gettime(CLOCK_MONOTONIC, &before);
    for (i = 0; i < NUMTESTS; i++) {
        test1();
    }
    clock_gettime(CLOCK_MONOTONIC, &after);

    checksum = 0;
    for (i = 0; i < TESTDATALEN/2; i++) {
        checksum += result[i];
    }
    printf("checksum: %llu\n", checksum);
    elapsed = difftime(after.tv_sec, before.tv_sec) + (after.tv_nsec - before.tv_nsec)/1.0e9;
    printf("arithmetic solution took %f seconds\n", elapsed);

    clock_gettime(CLOCK_MONOTONIC, &before);
    for (i = 0; i < NUMTESTS; i++) {
        test2();
    }
    clock_gettime(CLOCK_MONOTONIC, &after);

    checksum = 0;
    for (i = 0; i < TESTDATALEN/2; i++) {
        checksum += result[i];
    }
    printf("checksum: %llu\n", checksum);
    elapsed = difftime(after.tv_sec, before.tv_sec) + (after.tv_nsec - before.tv_nsec)/1.0e9;
    printf("256 entries table took %f seconds\n", elapsed);

    clock_gettime(CLOCK_MONOTONIC, &before);
    for (i = 0; i < NUMTESTS; i++) {
        test3();
    }
    clock_gettime(CLOCK_MONOTONIC, &after);

    checksum = 0;
    for (i = 0; i < TESTDATALEN/2; i++) {
        checksum += result[i];
    }
    printf("checksum: %llu\n", checksum);
    elapsed = difftime(after.tv_sec, before.tv_sec) + (after.tv_nsec - before.tv_nsec)/1.0e9;
    printf("32768 entries table took %f seconds\n", elapsed);

    clock_gettime(CLOCK_MONOTONIC, &before);
    for (i = 0; i < NUMTESTS; i++) {
        test4();
    }
    clock_gettime(CLOCK_MONOTONIC, &after);

    checksum = 0;
    for (i = 0; i < TESTDATALEN/2; i++) {
        checksum += result[i];
    }
    printf("checksum: %llu\n", checksum);
    elapsed = difftime(after.tv_sec, before.tv_sec) + (after.tv_nsec - before.tv_nsec)/1.0e9;
    printf("65536 entries table took %f seconds\n", elapsed);

    return 0;
}

Lets compile the thing:

允许编译:

$ gcc -O3 -g -Wall -Wextra test.c

And run it:

并运行:

$ ./a.out

The result:

结果:

  1. arithmetic solution: 437.17 s
  2. 算法解决方案:437.17秒
  3. 256 entries lookup table: 117.80 s
  4. 查询表:117.80 s。
  5. 32768 entries lookup table: 52.33 s
  6. 32768项查找表:52.33秒
  7. 65536 entries lookup table: 44.66 s
  8. 查询表:44.66秒

This we can conclude lookup tables beat arithmetic solutions any time and that wasting memory for bigger lookup tables might be worth the additional runtime.

我们可以得出这样的结论:查找表在任何时候都优于算术解决方案,为更大的查找表浪费内存可能值得额外的运行时。

#4


0  

void hex_binary(char * res){
char binary[16][5] = {"0000", "0001", "0010", "0011", "0100", "0101","0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110","1111"};
char digits [] = "0123456789abcdef";

const char input[] = "a9e6"; // input value
res[0] = '\0';
int p = 0;
int value =0;
    while(input[p])
    {
        const char *v = strchr(digits, tolower(input[p]));
        if(v[0]>96){
            value=v[0]-87;
        }
        else{
            value=v[0]-48;
        }
        if (v){
            strcat(res, binary[value]);
        }
        p++;
    }
    printf("Res:%s\n", res);
}

#5


-1  

void printBin(unsigned int num){
  char str[sizeof(num)*8];
  char *p = str;
  for(*p='0'; num; num/=2) { *p++='0'+num%2; } //store remainders
  for(--p; p>=str; putchar(*p--)) {;}          //print remainders in reverse
  putchar('\n');
}

#6


-2  

The quickest and easiest way is to read the hex file and, for each character ('0' through 'F') read, do a table lookup of the equivalent (0 through 15) binary value. There are, as ever, more elegant ways but this is very straightforward, maybe something like:

最快、最简单的方法是读取十六进制文件,对于读取的每个字符('0'到'F'),执行等价的(0到15)二进制值的表查找。和以往一样,也有更优雅的方式,但这是非常直接的,可能是这样的:

switch (charval) {
  case '0': binval = 0;
  case '1': binval = 1;
  case '2': binval = 2;
  case '3': binval = 3;
   ....
  case 'a': binval = 10;
  case 'b': binval = 11;
  case 'A': binval = 10;
  case 'B': binval = 11;
  ....
  case 'f':  binval = 15;
  case 'F':  binval = 15;
  default:   binval = -1;  // error case
}

Now you have to use shifts and IORs/ADDs to construct words of the size you want from these individual 4-bit binary values.

现在,您必须使用移位和ior / add来构造您想从这些单独的4位二进制值中获得的大小的字。

#7


-3  

That's my function to convert HEX to BIN, byte a byte.

这是我把十六进制转换成二进制的函数,一个字节。

void HexToBin(char hex_number, char* bit_number) {
    int max = 128;
    for(int i = 7 ; i >-1 ; i--){
        bit_number [i] = (hex_number & max ) ? 1 : 0;
        max >>=1;
    }
}

and the call to the function:

对函数的调用:

void main (void){

    char hex_number = 0x6E; //0110 1110
    char bit_number[8]={0,0,0,0,0,0,0,0};
    HexToBin(hex_number,bit_number);

    for(int i = 7 ; i >-1 ; i--)
        printf("%d",bit_number[i]);

    printf("\n");
    system("pause");
}

And here is the MSDOS answer:

下面是MSDOS的回答:

01101110

Press a key to continue . . .

Quite easy!

很简单!

#8


-3  

#include <stdio.h>

int main()
{
    long int binaryNumber,
             hexadecimalNumber = 0,
             j = 1,
             remainder;

    printf("Enter any number any binary number: ");
    scanf("%ld", &binaryNumber);

    while(binaryNumber != 0) {
        remainder = binaryNumber % 10;
        hexadecimalNumber = hexadecimalNumber + remainder * j;
        j = j * 2;
        binaryNumber = binaryNumber / 10;
    }
    printf("Equivalent hexadecimal value: %X", hexadecimalNumber);
    return 0;
}