I am having trouble with some of the logic in converting an IP Address range into a list of CIDR blocks. I do believe that this website is doing it right: http://ip2cidr.com/
I would like to pass in a starting IP address and an ending IP address and have the java spit out the minimum list of CIDR blocks required to cover only the range passed in and nothing more.
For instance, if I pass in a start address of 1.1.1.111 and an end address of 1.1.1.120, I would expect to get in return: 1.1.1.111/32 1.1.1.112/29 1.1.1.120/32
(with the /32 indicating a single address.)
The following CIDR blocks contain (not limited to) the range of addresses 1.1.1.111 - 1.1.1.120
/1 - /27
etc.
My last answer had some bugs in it that came about when the first octet of the IP address was too big. This one works better. Lifted almost entirely from here: http://facedroid.blogspot.com/2010/06/ip-range-to-cidr.html
You need to understand binary numbers, nothing more.
An CIDR block is nothing else than a series of binary numbers with common prefix and all possible suffixes. Assume for the example below we had 8-bit IP-addresses, with classes
/1
, ... to/8
.In your case (ignoring the 1.1.1 for now), we write your numbers as binary numbers:
You'll see that all numbers have a common
11
prefix, but our list does not contain all these numbers. So we have to split it in two lists - one with110
and one with111
. The first contains only one number, so we make a/8
block out of it (111/8
).The other list (from 112 to 120) contains not all numbers with
111
(since then it would go up to 127), so we split again - one list with1110
, the other with1111
. The first one is now the complete block1110????
(or112/4
), the second one is only one single address, namely11111000
(or120/8
).So, now only extend to 32 bit instead of 8, and implement in Java, and you are ready.
In mathematical terms, one block always goes from x * 2^n to (x+1) * 2^n - 1, and we then use 32 - n as the block-size suffix. So you only need to find the next multiple of some power of two.
I ended up repurposing some PHP code I had found and tweaking to my needs. Below is the class I ended up with.
I've got a few helper methods in there that, for the purposes of this question, clutter things up. But you can get the general idea.