The IPv6 range is given (hyphen delimiter): 2c0f:ffd8::-2c0f:ffd8:ffff:ffff:ffff:ffff:ffff:ffff

How to quickly calculate the number of IP addresses in this range?

  • 3
    The word "quickly" is superfluous. Or, let's clarify: you are not going to scan all IP ranges in search of responding devices, but just need to count the possible number of addresses, right? - AK
  • @AK, the word "fast" is just not superfluous. Scan all IP addresses that contain a range - not going. It is necessary to calculate only the call of IP addresses that contains the range. Counting by brute force, using the same IEnumerator (under the hood of which is the usual for and yield) or analogs - a very long time (though I have not tried to parallelize the calculations, but judging by the initial data - even they will be performed for a long time). - User12367
  • 6
    Option: from the end address to subtract the initial and add one, does not fit? Or not fast enough? - PetSerAl
  • PowerShell: function IPAddressAsBigInteger { param([IPAddress]$Addr) $Bytes = $Addr.GetAddressBytes(); [Array]::Reverse($Bytes); if($Bytes[-1] -ge 128) { [Array]::Resize([ref]$Bytes, $Bytes.Length+1) } [BigInt]$Bytes } $Begin, $End = '2c0f:ffd8::-2c0f:ffd8:ffff:ffff:ffff:ffff:ffff:ffff' -split '-'; (IPAddressAsBigInteger $End) - (IPAddressAsBigInteger $Begin) + 1 function IPAddressAsBigInteger { param([IPAddress]$Addr) $Bytes = $Addr.GetAddressBytes(); [Array]::Reverse($Bytes); if($Bytes[-1] -ge 128) { [Array]::Resize([ref]$Bytes, $Bytes.Length+1) } [BigInt]$Bytes } $Begin, $End = '2c0f:ffd8::-2c0f:ffd8:ffff:ffff:ffff:ffff:ffff:ffff' -split '-'; (IPAddressAsBigInteger $End) - (IPAddressAsBigInteger $Begin) + 1 function IPAddressAsBigInteger { param([IPAddress]$Addr) $Bytes = $Addr.GetAddressBytes(); [Array]::Reverse($Bytes); if($Bytes[-1] -ge 128) { [Array]::Resize([ref]$Bytes, $Bytes.Length+1) } [BigInt]$Bytes } $Begin, $End = '2c0f:ffd8::-2c0f:ffd8:ffff:ffff:ffff:ffff:ffff:ffff' -split '-'; (IPAddressAsBigInteger $End) - (IPAddressAsBigInteger $Begin) + 1 - PetSerAl

2 answers 2

In the address range of a special format, such as the one shown in your question (general prefix, and 00..00-ff ... ff), the number of addresses is very simple. The number of bits available to change is taken, and 2 is raised to this power.

So, your prefix 2c0f:ffd8 contains 8 * 4 = 32 bits, 96 changeable bits remain, which gives 2 ^ 96 = 79 228 162 514 264 337 593 543 950 336 different addresses.

    If you do not take into account the reserved address ranges, then the easiest way, as @PetSerAl wrote in the comments, is to convert both addresses into numbers and subtract one from the other.

    IPv6 contains 128 bits and its numerical value does not fit into either long or decimal , so for calculations you will need to use BigInteger (for this you need to connect System.Numerics ).

    To convert a translation, we translate the address into an array of bytes using IPAddress.GetAddressBytes , then use the BigInteger(byte[]) constructor.

    When converting you need to take into account differences in byte representation:

    • IPAddress.GetAddressBytes returns the bytes starting with the most significant bits, and BigInteger expects to get them in reverse order, so you need to flip the array;
    • BigInteger treats an array of bytes as a representation of a number with a sign (a number is considered negative if the high bit of the high byte is set). To avoid this, you can add 0 to the end of the array.

    An example of a method that converts an address string to a number:

     private static BigInteger AddressToBigInteger(string addressString) { var address = IPAddress.Parse(addressString); var bytes = address.GetAddressBytes(); Array.Reverse(bytes); Array.Resize(ref bytes, bytes.Length+1); return new BigInteger(bytes); } 

    Application:

     var first = AddressToBigInteger("2c0f:ffd8::"); var second = AddressToBigInteger("2c0f:ffd8:ffff:ffff:ffff:ffff:ffff:ffff"); Console.WriteLine(second - first + 1); //+1, чтобы включить обе границы диапазона 
    • one
      How many addresses in the range of 7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-8000:: ? - PetSerAl
    • @PetSerAl Thanks for the comment, fixed the error with the sign bit. Now it turns out 2. - default locale