Question

I am receiving a 128-bit binary address and I need to convert it into hexadecimal format. This is what I have to do:

  • I will receive 128-bit binary number
  • I need to divide it into 8 blocks of 16-bits each, so I will have 8 variables each having 16-bits.

    0010000111011010 0000000011010011 0000000000000000 0010111100111011 0000001010101010 0000000011111111 0000000000000000 0000000000000000

  • Now, I need to further divide these 16-bits into 4-bits each i.e a nibble

    0010 0001 1101 1010
    0000 0000 1101 0011
    0000 0000 0000 0000

  • So, now I will get four sub variables for each variable

  • Each variable is 16-bits long and sub variables are 4-bits long
  • Than, I need to convert each of these sub variables into hexadecimal

    0010 0001 1101 1010

    2 1 D A

  • Combine all the sub variables and form an IPv6 address in hexadecimal form:

    21DA:00D3:0000:2F3B:02AA:00FF:0000:0000

Can anyone tell me how to do it in C++?

Was it helpful?

Solution

To get the four highest bits of a 16-bit value, you shift it right by 12 bits. This will cause the top bits to be zeroes so no masking needed. For the others you (optionally) shift right and mask out the four lowest bits with the bitwise and operator &.

To make the value gotten from the above steps to a hexadecimal digit in character form, then for values lower than 10 add '0' (if you're on a computer with with ASCII encoding), and for values at 10 or higher then subtract ten and add e.g. 'A'.


There are simpler ways of course, like using e.g. sprintf to convert the number directly. Just get the 16-bit value into an unsigned short, and do e.g.

printf("%04hx\n", value_as_unsigned_short);

Let say you have the binary number 0001001010101011. This is, in hexadecimal presentation 12ab.

If the binary number is in an integer variable, lets say one named value, we can get the hexadecimal representation as a string like this:

// First get each digit, one by one
digit0 = value & 0x0f;  // Mask out everything but the lowest four bits
digit1 = (value >>  4) 0x0f;
digit2 = (value >>  8) 0x0f;
digit3 = value >> 12;

// Now make a string out of those four digits
char str[5];  // Four digits plus the string terminator

// If a digit is less than 10, then add '0'  to get an ASCII character
// Else decrease by ten (to get a number between 0 and 5) and add 'A'
str[0] = digit3 < 10 ? digit3 + '0' : (digit3 - 10) + 'A';
str[1] = digit2 < 10 ? digit2 + '0' : (digit2 - 10) + 'A';
str[2] = digit1 < 10 ? digit1 + '0' : (digit1 - 10) + 'A';
str[3] = digit0 < 10 ? digit0 + '0' : (digit0 - 10) + 'A';
str[4] = '\0'; // Terminate string

printf("value is in hex %s\n", str);

The above code will print

value is in hex 12AB

However that is a lot of code, though it can be reused for all numbers. If you already have your 16-bit number in the integer variable value, then it's much easier to just write

printf("value is in hex %04hX\n", value);

The result of both code snippets above will be just the same.


Regarding your edit:

std::ostringstream oss;
for (size_t i = 0; i < 8; ++i, aBinaryIPAddress += 2)
{
    // Take the first byte, and shift it left 8 bits, making it
    // the high byte of a 16-bit number. Then or (or add) the next
    // byte at the low 8 bits in the 16-bit number.
    // The casting is needed because we're working with 16-bit numbers
    // and not bytes.
    uint16_t value = static_cast<uint16_t>(*aBinaryIPAddress << 8) |
                     static_cast<uint16_t>(*(aBinaryIPAddress + 1));

    oss << std::setfill('0') << std::setw(4) << std::hex << value;
    if (i < 7)
        oss << ':';
}

std::cout << "Address is " << oss.str() << '\n';

OTHER TIPS

You can use sprintf and format specifier X to print a integer value as hexadecimal. No need to divide the blocks more than 4 bytes each. So if you have this:

string a = "00100001110110100000000011010011";
unsigned value = 0;
for (int i  = 0;i < a.size();++i) {
  value = value * 2 + a[i] - '0';
}
printf("%04X\n", value);

Will solve a big portion of your problem. I have used printf above to demonstrate the output on stdout.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top