本文介绍了我怎么能在C / C ++减去两个IPv6地址(128位数字)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我存储体sockaddr_in6 IP地址,支持的4个32位的数组,地址[4] 。基本上是一个128位的数字。

I'm storing the IP address in sockaddr_in6 which supports an array of four 32-bit, addr[4]. Essentially a 128 bit number.

我试图计算出在给定范围内的IPv6的IP(之间有多少IPS)的数量。所以它的减去从另一个使用两个阵列具有四的长度的问题。

I'm trying to calculate number of IPs in a given IPv6 range (how many IPs between). So it's a matter of subtracting one from another using two arrays with a length of four.

问题是因为没有 128bit的数据类型,我不能转换成十进制。

The problem is since there's no 128bit data type, I can't convert into decimal.

由于一吨!

推荐答案

您可以使用某种大INT库(如果你能忍受LGPL,GMP是选择)。幸运的是,128位的减法是容易的,如果有必要通过手工模拟。下面是计算的(A-B)的绝对值的快速和肮脏的示范,为128位值:

You could use some kind of big-int library (if you can tolerate LGPL, GMP is the choice). Fortunately, 128 bit subtraction is easy to simulate by hand if necessary. Here is a quick and dirty demonstration of computing the absolute value of (a-b), for 128 bit values:

#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; 
}

这给你差的绝对值。如果范围不是很大(64位或更少),那么 ipAddressA.lo 可以是你的答案作为一个简单的无符号长长

This gives you the absolute value of the difference. If the range is not huge (64 bits or less), then ipAddressA.lo can be your answer as a simple unsigned long long.

如果您有PERF顾虑,你可以,如果你希望它是该处理器的最佳使用编译器内在函数的采取一定的结构,如AMD64的优势。 _subborrow_u64 是AMD64内在进行必要的减法的工作。

If you have perf concerns, you can make use of compiler intrinsics for taking advantage of certain architectures, such as amd64 if you want it to be optimal on that processor. _subborrow_u64 is the amd64 intrinsic for the necessary subtraction work.

这篇关于我怎么能在C / C ++减去两个IPv6地址(128位数字)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 03:28