In this tutorial, we will demonstrate you on how to convert IP address ranges into CIDR format. CIDR format, Classless Inter-Domain Routing, is a compact representation of an IP address and its associated routing prefix. An example of CIDR notation, 8.8.8.0/24, which represents the IP ranges from 8.8.8.0 to 8.8.8.255. Please take note that this tutorial only for the conversion of IPv4 to CIDR format.
This tutorial will not display you a complete project, but the core function of how the conversion work. This function, iprange2cidr, takes 2 input parameters, namely the ipStart and ipEnd, the starting and the ending of an IP address respectively. You can either supply the IP address in dotted format, for example, 202.186.13.4, or IP number, for example, 3401190660, as the input parameters. The function will convert them into IP number if the dotted IP address format was supplied and perform the calculation.
Below are the sample codes of the function written in several programming languages, such as PHP, VB.NET, C#, Java and Ruby.
<?php function iprange2cidr($ipStart, $ipEnd){ if (is_string($ipStart) || is_string($ipEnd)){ $start = ip2long($ipStart); $end = ip2long($ipEnd); } else{ $start = $ipStart; $end = $ipEnd; } $result = array(); while($end >= $start){ $maxSize = 32; while ($maxSize > 0){ $mask = hexdec(iMask($maxSize - 1)); $maskBase = $start & $mask; if($maskBase != $start) break; $maxSize--; } $x = log($end - $start + 1)/log(2); $maxDiff = floor(32 - floor($x)); if($maxSize < $maxDiff){ $maxSize = $maxDiff; } $ip = long2ip($start); array_push($result, "$ip/$maxSize"); $start += pow(2, (32-$maxSize)); } return $result; } function iMask($s){ return base_convert((pow(2, 32) - pow(2, (32-$s))), 10, 16); } ?>
Public Function IPrange2cidr(ByVal ipStart As String, ipEnd As String) As List(Of String) Dim startIP As Long = IP2Long(ipStart) Dim endIP As Long = IP2Long(ipEnd) Dim result As List(Of String) = New List(Of String) While (endIP >= startIP) Dim maxSize As Byte = 32 While (maxSize > 0) Dim mask As Long = IMask(maxSize - 1) Dim maskBase As Long = startIP And mask If maskBase <> startIP Then Exit While End If maxSize -= 1 End While Dim x As Double = Math.Log(endIP - startIP + 1) / Math.Log(2) Dim maxDiff As Byte = (32 - Math.Floor(x)) If maxSize < maxDiff Then maxSize = maxDiff End If Dim ip As String = Long2IP(startIP) result.Add(ip + "/" + Convert.ToString(maxSize)) startIP += Math.Pow(2, (32 - maxSize)) End While Return result End Function Public Function IPrange2cidr(ByVal ipStart As Integer, ipEnd As Integer) As List(Of String) Dim startIP As Long = ipStart Dim endIP As Long = ipEnd Dim result As List(Of String) = New List(Of String) While (endIP >= startIP) Dim maxSize As Byte = 32 While (maxSize > 0) Dim mask As Long = IMask(maxSize - 1) Dim maskBase As Long = startIP And mask If maskBase <> startIP Then Exit While End If maxSize -= 1 End While Dim x As Double = Math.Log(endIP - startIP + 1) / Math.Log(2) Dim maxDiff As Byte = (32 - Math.Floor(x)) If maxSize < maxDiff Then maxSize = maxDiff End If Dim ip As String = Long2IP(startIP) result.Add(ip + "/" + Convert.ToString(maxSize)) startIP += Math.Pow(2, (32 - maxSize)) End While Return result End Function Private Function IMask(ByVal s As Integer) As Long Return Math.Pow(2, 32) - Math.Pow(2, (32 - s)) End Function Private Function IP2Long(ByVal ipAddress As String) As Long Dim ip As System.Net.IPAddress = Net.IPAddress.Parse(ipAddress) Return (CLng(ip.GetAddressBytes(0)) << 24) Or (CInt(ip.GetAddressBytes(1)) << 16) Or (CInt(ip.GetAddressBytes(2)) << 8) Or ip.GetAddressBytes(3) End Function Private Function Long2IP(ByVal ipAddress As Long) As String Dim tmpIP As New Net.IPAddress(ipAddress) Dim bytes() As Byte = tmpIP.GetAddressBytes() Array.Reverse(bytes) Dim addr As Long = CLng(BitConverter.ToUInt32(bytes, 0)) Return New Net.IPAddress(addr).ToString() End Function
public static List<string> iprange2cidr(string ipStart, string ipEnd) { long start = ip2long(ipStart); long end = ip2long(ipEnd); var result = new List<string>(); while (end >= start) { byte maxSize = 32; while (maxSize > 0) { long mask = iMask(maxSize - 1); long maskBase = start & mask; if (maskBase != start) { break; } maxSize--; } double x = Math.Log(end - start + 1) / Math.Log(2); byte maxDiff = (byte)(32 - Math.Floor(x)); if (maxSize < maxDiff) { maxSize = maxDiff; } string ip = long2ip(start); result.Add(ip + "/" + maxSize); start += (long)Math.Pow(2, (32 - maxSize)); } return result; } public static List<string> iprange2cidr(int ipStart, int ipEnd) { long start = ipStart; long end = ipEnd; var result = new List<string>(); while (end >= start) { byte maxSize = 32; while (maxSize > 0) { long mask = iMask(maxSize - 1); long maskBase = start & mask; if (maskBase != start) { break; } maxSize--; } double x = Math.Log(end - start + 1) / Math.Log(2); byte maxDiff = (byte)(32 - Math.Floor(x)); if (maxSize < maxDiff) { maxSize = maxDiff; } string ip = long2ip(start); result.Add(ip + "/" + maxSize); start += (long)Math.Pow(2, (32 - maxSize)); } return result; } private static long iMask(int s) { return (long)(Math.Pow(2, 32) - Math.Pow(2, (32 - s))); } private static string long2ip(long ipAddress) { System.Net.IPAddress ip; if (System.Net.IPAddress.TryParse(ipAddress.ToString(), out ip)) { return ip.ToString(); } return ""; } private static long ip2long(string ipAddress) { System.Net.IPAddress ip; if (System.Net.IPAddress.TryParse(ipAddress, out ip)) { return (((long)ip.GetAddressBytes()[0] << 24) | ((long)ip.GetAddressBytes()[1] << 16) | ((long)ip.GetAddressBytes()[2] << 8) | ip.GetAddressBytes()[3]); } return -1; }
public static List<String> iprange2cidr( String ipStart, String ipEnd ) { long start = ip2long(ipStart); long end = ip2long(ipEnd); ArrayList<String> result = new ArrayList<String>(); while ( end >= start ) { byte maxSize = 32; while ( maxSize > 0) { long mask = iMask( maxSize - 1 ); long maskBase = start & mask; if ( maskBase != start ) { break; } maxSize--; } double x = Math.log( end - start + 1) / Math.log( 2 ); byte maxDiff = (byte)( 32 - Math.floor( x ) ); if ( maxSize < maxDiff) { maxSize = maxDiff; } String ip = long2ip(start); result.add( ip + "/" + maxSize); start += Math.pow( 2, (32 - maxSize) ); } return result; } public static List<String> iprange2cidr( int ipStart, int ipEnd ) { long start = ipStart; long end = ipEnd; ArrayList<String> result = new ArrayList<String>(); while ( end >= start ) { byte maxSize = 32; while ( maxSize > 0) { long mask = iMask( maxSize - 1 ); long maskBase = start & mask; if ( maskBase != start ) { break; } maxSize--; } double x = Math.log( end - start + 1) / Math.log( 2 ); byte maxDiff = (byte)( 32 - Math.floor( x ) ); if ( maxSize < maxDiff) { maxSize = maxDiff; } String ip = long2ip(start); result.add( ip + "/" + maxSize); start += Math.pow( 2, (32 - maxSize) ); } return result; } private static long iMask(int s) { return Math.round(Math.pow(2, 32) - Math.pow(2, (32 - s))); } private static long ip2long(String ipstring) { String[] ipAddressInArray = ipstring.split("\\."); long num = 0; long ip = 0; for (int x = 3; x >= 0; x--) { ip = Long.parseLong(ipAddressInArray[3 - x]); num |= ip << (x << 3); } return num; } private static String long2ip(long longIP) { StringBuffer sbIP = new StringBuffer(""); sbIP.append(String.valueOf(longIP >>> 24)); sbIP.append("."); sbIP.append(String.valueOf((longIP & 0x00FFFFFF) >>> 16)); sbIP.append("."); sbIP.append(String.valueOf((longIP & 0x0000FFFF) >>> 8)); sbIP.append("."); sbIP.append(String.valueOf(longIP & 0x000000FF)); return sbIP.toString(); }
require 'ipaddr' def iprange2cidr(ipstart, ipend) if ipstart.kind_of?(String) || ipend.kind_of?(String) startR = ip2long(ipstart) endR = ip2long(ipend) else startR = ipstart endR = ipend end result = Array.new while endR >= startR do maxSize = 32 while maxSize > 0 do mask = (iMask(maxSize - 1)) maskBase = startR & mask if maskBase != startR break end maxSize-=1 end x = Math.log(endR - startR + 1)/Math.log(2) maxDiff = (32 - x.floor).floor if maxSize < maxDiff maxSize = maxDiff end ip = long2ip(startR) cidr = [ip, maxSize].join('/') result.push cidr startR += 2**(32-maxSize) end return result end def iMask(s) return (2**32 - 2**(32-s)) end def long2ip(num) return IPAddr.new(num, Socket::AF_INET).to_s end def ip2long(ip) return IPAddr.new(ip).to_i end
The result that return by the iprange2cidr function is an Array that contains the list of CIDR formatted IP address. Looping has to be done to get all the CIDR formatted IP address from the return result. The following figure shows the sample output with ipStart:192.168.1.0 and ipEnd:192.168.1.9 of the converting IP address ranges into CIDR format.