0

我收到一个 128 位二进制地址,我需要将其转换为十六进制格式。这是我必须做的:

  • 我将收到 128 位二进制数
  • 我需要将它分成 8 个 16 位的块,所以我将有 8 个变量,每个变量都有 16 位。

    0010000111011010 0000000011010011 0000000000000000 0010111100111011 0000001010101010 000000001111111 0000000000000000 00000000

  • 现在,我需要将这些 16 位进一步划分为 4 位,即一个半字节

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

  • 所以,现在我将为每个变量获得四个子变量

  • 每个变量为 16 位长,子变量为 4 位长
  • 比,我需要将这些子变量中的每一个转换为十六进制

    0010 0001 1101 1010

    2 1 大

  • 组合所有子变量,形成一个十六进制形式的 IPv6 地址:

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

谁能告诉我如何在 C++ 中做到这一点?

4

2 回答 2

3

要获得 16 位值的四个最高位,请将其右移 12 位。这将导致最高位为零,因此不需要屏蔽。对于其他人,您(可选)右移并使用按位和运算符屏蔽掉四个最低位&

要将从上述步骤中得到的值转换为字符形式的十六进制数字,然后对于低于 10 的值添加'0'(如果您在使用 ASCII 编码的计算机上),对于 10 或更高的值,然后减去 10 并添加例如'A'


当然还有更简单的方法,比如使用 egsprintf直接转换数字。只需将 16 位值转换为无符号短整数,然后执行例如

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

假设你有二进制数0001001010101011。这是,以十六进制表示12ab

如果二进制数在一个整数变量中,假设一个名为value,我们可以将十六进制表示为一个字符串,如下所示:

// 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);

上面的代码将打印

值为十六进制 12AB

然而,这是很多代码,尽管它可以用于所有数字。如果整数变量中已经有 16 位数字value,那么编写起来会容易得多

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

上面两个代码片段的结果是一样的。


关于您的编辑:

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';
于 2013-11-05T09:48:17.693 回答
2

您可以使用 sprintf 和格式说明符 X 将整数值打印为十六进制。无需将每个块划分超过 4 个字节。所以如果你有这个:

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

将解决您的大部分问题。我使用上面的 printf 来演示 stdout 上的输出。

于 2013-11-05T09:47:29.990 回答