How can I subtract two IPv6 addresses (128bit numbers) in C/C++?

后端 未结 2 982
长发绾君心
长发绾君心 2021-01-02 20:35

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

I\'m trying

2条回答
  •  长发绾君心
    2021-01-02 21:07

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

    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.

    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.

提交回复
热议问题