The most banal situation is extremely common, but I have a problem with it. The bottom line is, you need to translate HEX into BIN , for this, there is a function, HexToBin , but I can’t implement it at all, they write on the forums that it is inconvenient. And all this needs to be written to a text file, I have not yet come across these functions.

I would appreciate a brief example of using HexToBin , C ++.

4 answers 4

Since you wrote C++ in tags, I’ll answer in C++ style rather than, for example, C

The standard way to solve the translation of X->binary and vice versa is to use std::bitset .

Here is an example of use:

 const std::string string("0x31c3"); std::istringstream stream(string); int i; stream >> std::hex >> i; std::cout << '"' << string << "\": " << i << "(0x" << std::hex << i << ")\n"; std::bitset<16> bitset = i; // 'to_string' вернет строку std::string формата '000...0111' std::cout << "Binary : " << bitset.to_string<char, std::char_traits<char>, std::allocator<char> >() << std::endl; 

    A very useful task to comprehend. And understand what should be the input and output. It also becomes clear that the task can be divided into two stages: 1. Getting a number from a string in a hex-form and bringing it to a "human form" 2. Converting a string representation of a binary representation.

    For item 1, I can suggest using a completely standard function strtol. Her beauty is that she herself can cut off 0x and she can rip the number out of the string in any number system. The functions sscanf, scanf, fscanf are also able to take a hexadecimal number as a string at the input and correctly store the value in the type variable int. Well, or you can use the method with threads with ++. Do as you understand.

    You can also use C functions to convert to a binary view. ltoa and ltostr fit. Otherwise, you will have to manually calculate the remainder of the division into two and add them to the line in the correct order.

    It is probably easier than to suffer like this, to use the simplest idea — there is a simple correspondence between hexadecimal and binary notation. Each hex digit corresponds to a specific quadruple of bits. Those. you can even stupidly make a table of the form 0-0000, 1-0001 .... a-1010..f-1111. And you can simply replace the character with a substring free then convert the type of record numbers.

      The output of characters (digits) of a number in the desired number system (in your case 2) consists in cyclically calculating the residuals from dividing the number by the base of the number system (namely, they must be output (in the reverse order)) and then dividing the number by the base. The cycle continues until the number is greater than zero. For negative modification is obvious.

      For your case and (suppose this is the maximum) 64-bit integers, a buffer of 66 characters is sufficient (taking into account the sign and the line terminator). Fill it from right to left, and then copy everything that led to the beginning. Instead of dividing, you can use the right shift (x >> 1), and instead of calculating the remainder, check the low-order bit (x & 1).

        Each hexadecimal digit goes into exactly 4 binary digits: A 16 = 1010 2 .

        Therefore, it is easy to write code that turns an arbitrarily large hex-string into a “01” line — for each hex-digit, add the corresponding bits to the result:

         #include <string> #include "hex2bin_table.h" /// hex: "A" -> "1010", else: "\n" -> "\n" std::string hex2bin(const std::string& hex) { std::string bits; for (unsigned char hex_digit : hex) bits += hex2bin_table[hex_digit]; return bits; } 

        To avoid multiple allocations when the bits grow, strings can be added before the loop: bits.reserve(4 * hex.size()) . But you should measure your performance to see what effect this has on your case.

        Example:

         #include <iostream> int main() { std::string hex = "CAFEBABE\n8BADF00D\nDEADBEEF\nD15EA5E"; std::cout << hex2bin(hex) << std::endl; } 

        Result

         11001010111111101011101010111110 10001011101011011111000000001101 11011110101011011011111011101111 1101000101011110101001011110 

        To check, you can turn the bits into hexadecimal digits, for example, on Python:

         >>> 0b11001010111111101011101010111110 .to_bytes(4, 'big').hex() 'cafebabe' 

        hex2bin_table is the table hex -> bin, in which for each hex digit there is a corresponding bit string:

         const char* const hex2bin_table[] = { "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", ... "\x28", "\x29", "\x2A", "\x2B", "\x2C", "\x2D", "\x2E", "\x2F", "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "\x3A", "\x3B", "\x3C", "\x3D", "\x3E", "\x3F", ... }; 

        The line position is determined by the ASCII code for the corresponding hex number: 'A' == 65 , therefore hex2bin_table['A'] == hex2bin_table[65] == "1010" . Bytes that do not correspond to hexadecimal ASCII digits represent themselves as C lines: hex2bin_table[0x2e] == "\x2e" .

        The table can be generated automatically, for example on Python:

         #!/usr/bin/env python from string import hexdigits print('const char* const hex2bin_table[] = {') for char in map(chr, range(0x100)): if char in hexdigits: # interpret as hex-digit and print as bits print('"{:04b}",'.format(int(char, 16))) else: # as itself print(r'"\x{:02X}",'.format(ord(char))) print('};') 

        or instead of a table, you can use the function with a simple switch(hex_digit) branch .