sha*_*man 6 c c++ networking ipv6
我正在存储sockaddr_in6支持四个32位数组addr [4]的IP地址.基本上是一个128位的数字.
我正在尝试计算给定IPv6范围内的IP数量(两者之间的IP数).所以这是使用两个长度为4的数组从一个减去另一个的问题.
问题是因为没有128位数据类型,我无法转换为十进制.
万分感谢!
您可以使用某种 big-int 库(如果您可以容忍 LGPL,则选择 GMP)。幸运的是,如有必要,128 位减法很容易手动模拟。下面是计算 128 位值的 (ab) 绝对值的快速而简单的演示:
#include <iostream>
#include <iomanip>
struct U128
{
unsigned long long hi;
unsigned long long lo;
};
bool subtract(U128& a, U128 b)
{
unsigned long long carry = b.lo > a.lo;
a.lo -= b.lo;
unsigned long long carry2 = b.hi > a.hi || a.hi == b.hi && carry;
a.hi -= carry;
a.hi -= b.hi;
return carry2 != 0;
}
int main()
{
U128 ipAddressA = { 45345, 345345 };
U128 ipAddressB = { 45345, 345346 };
bool carry = subtract(ipAddressA, ipAddressB);
// Carry being set means that we underflowed; that ipAddressB was > ipAddressA.
// Lets just compute 0 - ipAddressA as a means to calculate the negation
// (0-x) of our current value. This gives us the absolute value of the
// difference.
if (carry)
{
ipAddressB = ipAddressA;
ipAddressA = { 0, 0 };
subtract(ipAddressA, ipAddressB);
}
// Print gigantic hex string of the 128-bit value
std::cout.fill ('0');
std::cout << std::hex << std::setw(16) << ipAddressA.hi << std::setw(16) << ipAddressA.lo << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供差异的绝对值。如果范围不大(64 位或更少),那么ipAddressA.lo您的答案可以是简单的unsigned long long.
如果您有性能问题,您可以利用编译器内在函数来利用某些架构,例如 amd64(如果您希望它在该处理器上达到最佳效果)。_subborrow_u64是进行必要的减法运算的 amd64 内在函数。