Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm wondering if there is a formula to work out the amount of IP addresses in a given range.

I have a system that takes either a single IP address or a start and and end IP address:

  • A single one might be: 145.16.23.241
  • A range might be: 145.16.23.122 - 145.16.23.144

The people inputting these aren't technical, nor are they receiving these details from technical people, so suggesting using CIDR notation isn't an answer for me.

I want to be able to highlight that when entering a range such as: 122.100.10.12 - 128.10.200.140 it might not actually be a range and rather 2 singular IP addresses since such a range would comprise of x (large number of) IP addresses.

Is there a basic formula to help me highlight this?

share|improve this question
4  
abs(ip2-ip1)+1 –  Jörg W Mittag May 29 at 11:57
3  
Related... codegolf.stackexchange.com/questions/28760/… –  billpg May 29 at 18:45

4 Answers 4

up vote 20 down vote accepted

IP addresses are a 32 bit integer which we typically express as four octets for human purposes. You could get the number of addresses in a range by turning both into their 32 bit integer representations and subtracting.

share|improve this answer
    
I take back my comment. I think this is a more precise answer. –  Neil May 29 at 13:03
8  
This potentially counts broadcast addresses as valid IPs, which you probably don't want to do. You'd have to know what subnet(s) are involved to get an accurate count excluding those. If you just need an estimate, or it's all one subnet, this oughta be perfect. –  Tim S. May 29 at 15:16
    
@TimS. given the OP's description of why he wants to do this, the broadcast addresses should be no problem. In the general case, they could be though –  Cruncher May 29 at 16:57

You won't be able to get an accurate count without any information about whether the range crosses subnet boundaries and what those subnets are. For example, 10.10.7.0 - 10.10.8.255 is a contiguous range of 512 addresses in the context of a /16. If that range covers two /24 blocks, the count is 508 because each block has a network address and a broadcast address.

Making sure the entered upper bound is greater than or equal to the lower bound and using subtraction to measure the distance between them is good for a quick sanity check. You'll need to decide what's a reasonable difference before you raise the red flag.

After you've converted each octet to an 8-bit integer, converting the lot of them to a single 32-bit integer is a matter of doing this:

(octet1 << 24) | (octet2 << 16) | (octet3 << 8) | octet4
share|improve this answer
2  
To the laymen: octet1*2^24 + octet2*2^16 + octet3*2^8 + octet4 –  Neil May 29 at 13:54
    
I agree that the subnets determine how many truly usable IP addresses are in the range, however for the OP's purposes that's mostly irrelevant. Instead, he's trying to give an order of magnitude for how many raw IP addresses there are, for which the occasional broadcast and network address don't need to be removed. –  ErikE May 29 at 21:02
    
@ErikE: See second paragraph, "...good for a quick sanity check." –  Blrfl May 30 at 11:24
    
You're completely right! –  ErikE May 30 at 20:17

You have to be clear how you are defining these ranges. Maybe you meant all of the addresses whose 32-bit representations fall between the two numbers, and that's what the other answers here seem to assume. So for example, 1.0.0.0 - 1.0.2.0 includes all of the following IP addresses:

1.0.0.0 - 1.0.0.255
1.0.1.0 - 1.0.1.255
1.0.2.0

However, when I first read your question, what I thought you meant was defining separate ranges for each byte, in which case the range 1.0.0.0 - 1.0.2.0 would mean only the following three addresses:

1.0.0.0
1.0.1.0
1.0.2.0

For the first case, as others stated the correct answer is

abs(ip2-ip1)+1 

But in the second case, the correct answer would be

product(abs(ip2[i] - ip1[i]) + 1) 

where [i] means the ith byte of that IP, and the product is taken over the four bytes.

Make sure it's clear to your users which of these you mean.

share|improve this answer

Note that to properly convert dotted IP addresses to a 32-bit number and do mathy things on them reliably, you need to use an unsigned integer type. If the only integer types available to you are signed, then...

Another way to calculate it is this: starting with the first octet that is different, multiply each octet's difference from that point on by the following numbers, and then add these differences together:

1: 16777216
2: 65536
3: 256
4: 1

For example, using your range 122.100.10.12 - 128.10.200.140:

  128  10   200  140
- 122  100   10   12
=   6 -90   190  128

= 16777216 * 6 
+ 65536 * -90
+ 256 * 190
+ 1 * 128
= 94813824

This is the same value you'd get doing the whole conversion of

0x800AC88C = 2148190348
0x7A640A0C = 2053376524

and then subtracting.

Additionally, you can also perform the same operation this way:

((a[0] - b[0]) * 256 + a[1] - b[1]) * 256 + a[2] - b[2]) * 256 + a[3] - b[3]

This is easily susceptible to a reduce that collapses each next pair of values repeatedly.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.