# Solution For Ip To Cidr

The ‘IP to CIDR’ problem on LeetCode asks us to take an IP address as well as a number, and then to output a list of CIDR blocks with the given number of IP addresses as requested.

A CIDR block is a range of IP addresses that are all covered by the same subnet mask. For example, the IP address 192.168.1.1 might be covered by the CIDR block 192.168.1.0/24, which means that the first 24 bits of the IP address are fixed and the remaining 8 bits can take on any value between 0 and 255.

To solve this problem, we can follow the following approach:

1. Convert the IP address to a 32-bit binary string: We can start by taking the given IP address and splitting it into four decimal numbers. Then, we can convert each of these decimal numbers to an 8-bit binary number and concatenate them together to form a 32-bit binary string.

For example, if the input IP address is “255.0.0.7”, we can convert it to the binary string “11111111000000000000000000000111”.

1. Compute the number of addresses requested: We are given a number ‘n’ that represents the number of IP addresses that we need to cover. To find the size of the CIDR block that we need, we can keep halving the number of addresses requested until we reach a power of 2. This is because a CIDR block always has a size that is a power of 2.

For example, if n=10, we can keep halving it until we reach a power of 2: 10 -> 5 -> 2 -> 1. Therefore, we need a CIDR block of size 2^3=8.

1. Calculate the prefix length of the CIDR block: The prefix length of a CIDR block represents the number of leading bits in the subnet mask. To calculate this, we can count the number of consecutive 1’s starting from the most significant bit of the binary IP address until we reach a count that is greater than or equal to the log base 2 of the number of requested addresses.

For example, if the binary IP address is “11111111000000000000000000000111”, and we need to cover 8 addresses, we can count the number of leading 1’s: 11111111. Since this is 8 bits long and 2^3=8, the prefix length of the CIDR block is 8.

1. Generate the CIDR blocks: Once we have the binary IP address and the prefix length, we can use these to generate the CIDR blocks. We can start by taking the prefix and using it to generate a subnet mask (by setting the first ‘prefix’ bits to 1 and the remaining bits to 0). Then, we can use this subnet mask to split the IP address into multiple blocks, each of size equal to the number of requested addresses.

For example, if the binary IP address is “11111111000000000000000000000111” and we need to cover 8 addresses, we can calculate the subnet mask as “11111111000000000000000000000000”. Then, we can split the IP address into 8 blocks, each with a size of 1 address:

• 11111111000000000000000000000000 (first block: 255.0.0.0/32)
• 11111111000000000000000000000100 (second block: 255.0.0.4/30)
• 11111111000000000000000000001000 (third block: 255.0.0.8/29)
• 11111111000000000000000000001100 (fourth block: 255.0.0.12/30)
• 11111111000000000000000000010000 (fifth block: 255.0.0.16/29)
• 11111111000000000000000000010100 (sixth block: 255.0.0.20/30)
• 11111111000000000000000000011000 (seventh block: 255.0.0.24/29)
• 11111111000000000000000000011100 (eighth block: 255.0.0.28/30)

We can generate the blocks in this way by iterating over the binary IP address and subnet mask, and dividing the address into blocks according to the size requested.

Now we can combine all these steps to get the solution for the problem. Here is the complete Python code:

“`
def ipToCIDR(ip: str, n: int) -> List[str]:
# Convert the IP address to binary
ip_num = 0
for x in ip.split(‘.’):
ip_num = ip_num * 256 + int(x)
ip_bin = “{0:b}”.format(ip_num)

``````# Calculate CIDR blocks
blocks = []
while n > 0:
# Find the largest power of 2 that is <= n

# Calculate the prefix length
prefix_len = 0
prefix_len += 1

# Add the CIDR block to the list
blocks.append(ip_num_to_ip_str(ip_num) + '/' + str(32 - prefix_len))

return blocks
``````

def ip_num_to_ip_str(ip_num: int) -> str:
return ‘.’.join(str((ip_num >> (8 * i)) % 256) for i in range(4)[::-1])
“`

The ‘ipToCIDR’ function takes two inputs: a string representing the IP address and an integer representing the number of addresses required. The function uses the approach outlined above to generate the CIDR blocks, and returns a list of strings representing the CIDR blocks.

The ‘ip_num_to_ip_str’ function is a helper function that takes a 32-bit integer representing an IP address in binary format and converts it to a string representation in decimal format.

The time complexity of this function is O(n), where n is the number of requested addresses. This is because we may need to generate up to n CIDR blocks. The space complexity is also O(n), since we need to store the CIDR blocks in a list.

## Step by Step Implementation For Ip To Cidr

```/**
* Given a start IP address and a number of IP addresses to be allocated,
* this function returns a list of CIDR blocks that cover the range.
*
* @param startIp The starting IP address in integer form
* @param numIps The number of IP addresses to be generated
* @return A list of CIDR blocks
*/
public List ipToCidr(String startIp, int numIps) {
// Convert start IP to long
long ip = ipToLong(startIp);

// Initialize list of CIDR blocks
List cidrs = new ArrayList<>();

// While we still need to allocate IP addresses
while (numIps > 0) {
// Get the number of IPs that can be allocated in this CIDR block
int numAllocatedIps = getNumAllocatedIps(ip);

// Add the CIDR block to the list

// Increment the IP to the next block
ip += numAllocatedIps;

// Decrement the number of IPs to be allocated
numIps -= numAllocatedIps;
}

return cidrs;
}

/**
* Converts an IP address in string form to long form.
*
* @param ip The IP address in string form
* @return The IP address in long form
*/
private long ipToLong(String ip) {
// Split the IP address into octets
String[] octets = ip.split("\\.");

// Convert each octet to an integer and add it to the long
long result = 0;
for (int i = 0; i < octets.length; i++) {
result += Integer.parseInt(octets[i]) << ((3 - i) * 8);
}

return result;
}

/**
* Converts an IP address in long form to string form.
*
* @param ip The IP address in long form
* @return The IP address in string form
*/
private String longToIp(long ip) {
// Convert the long to an array of octets
int[] octets = new int;
for (int i = 0; i < 4; i++) {
octets[i] = (int) (ip >> ((3 - i) * 8)) & 0xFF;
}

// Join the octets together with periods
return octets + "." + octets + "." + octets + "." + octets;
}

/**
* Gets the number of IP addresses that can be allocated in a CIDR block
* starting at the given IP.
*
* @param startIp The starting IP address
* @return The number of IP addresses that can be allocated
*/
private int getNumAllocatedIps(long startIp) {
// Initialize the number of allocated IPs to 1 (for the start IP)
int numAllocatedIps = 1;

// Initialize the current IP to the start IP
long curIp = startIp;

// While the next IP is not the end of the block
while ((curIp & 1) == 0 && curIp < startIp + numAllocatedIps) {
// Increment the number of allocated IPs
numAllocatedIps <<= 1;

// Move to the next IP
curIp++;
}

return numAllocatedIps;
}

/**
* Gets the CIDR prefix for a given number of IP addresses.
*
* @param numIps The number of IP addresses
* @return The CIDR prefix
*/
private int getCidrPrefix(int numIps) {
// Initialize the number of bits to 1 (for the start IP)
int numBits = 1;

// While the number of IPs is not a power of 2
while (numIps > 1) {
// Halve the number of IPs
numIps /= 2;

// Increment the number of bits
numBits++;
}

return 32 - numBits;
}```
```def ipToCIDR(self, ip, n):
#convert ip to int
int_ip = self.ip2int(ip)
#find the starting number and number of ips that can be represented by a /32
start = int_ip
while n > 0:
curr = start
while (curr & 1) == 0 and curr <= start + n:
curr >>= 1
n -= 1 - (start - curr)
start = curr + 1
#find the number of bits that need to be flipped to get to the next number that can be represented by a /32
bits = 0
while (start & 1) == 0:
start >>= 1
bits += 1
#add the starting number and number of bits to the output
return [str(start) + '/' + str(32 - bits)]```
```/**
* @param {number} ip
* @param {number} n
* @return {string[]}
*/
var ipToCIDR = function(ip, n) {
// Convert ip to binary string
let ipBin = ip.toString(2);

// Pad ipBin to 32 bits
while (ipBin.length < 32) {
ipBin = '0' + ipBin;
}

// Initialize result
const result = [];

// Helper function to convert binary string to CIDR notation
const toCIDR = (bin, count) => {
// Convert back to number
const num = parseInt(bin, 2);
// Determine number of bits in CIDR notation
const bits = 32 - Math.floor(Math.log2(count));
// Append CIDR notation to result
result.push(`\${num.toString()}/\${bits}`);
};

// While n > 0
while (n > 0) {
// Find position of first 1 in ipBin
let pos = ipBin.indexOf('1');
// If position is -1, that means ipBin is all 0's
if (pos === -1) {
// Add 1 to ip and convert to binary string
ipBin = (ip + 1).toString(2);
// Pad ipBin to 32 bits
while (ipBin.length < 32) {
ipBin = '0' + ipBin;
}
// Recurse with updated ipBin
toCIDR(ipBin, n);
// Exit loop
break;
}
// If position is not -1, that means ipBin has at least 1 1
else {
// If n is less than 2^(pos - 1), that means we can cover all of n with a CIDR notation starting at this position
if (n < Math.pow(2, pos - 1)) {
// Slice ipBin from position to end
ipBin = ipBin.slice(pos);
// Recurse with updated ipBin and n
toCIDR(ipBin, n);
// Exit loop
break;
}
// If n is greater than or equal to 2^(pos - 1), that means we need to continue searching for 1's
else {
// Set ipBin[pos] to 0
ipBin = ipBin.substring(0, pos) + '0' + ipBin.substring(pos + 1);
// Recurse with updated ipBin and n
toCIDR(ipBin, Math.pow(2, pos - 1));
// Update n
n -= Math.pow(2, pos - 1);
// Update ip
ip += Math.pow(2, pos - 1);
}
}
}

// Return result
return result;
};```
```class Solution {
public:
vector ipToCIDR(string ip, int n) {

// Split the ip string into 4 octets
istringstream iss(ip);
vector octets((istream_iterator(iss)),
istream_iterator());

// Convert the octets to integers
vector octets_int;
for (int i = 0; i < 4; i++) {
octets_int.push_back(stoi(octets[i]));
}

// Initialize the result vector
vector result;

// While there are still IP addresses to cover
while (n > 0) {

// Calculate the number of bits we can cover with the current IP
int bits = 32;
for (int i = 3; i >= 0; i--) {
if (octets_int[i] == 0) {
bits -= 8;
}
else {
break;
}
}

// While the number of bits we can cover is greater than the number
// of IP addresses we need to cover
while (bits > n) {
bits--;
}

result.push_back(ip + "/" + to_string(bits));

// Calculate the next IP address
int carry = 1;
for (int i = 3; i >= 0; i--) {
octets_int[i] += carry;
carry = octets_int[i] / 256;
octets_int[i] %= 256;
}

// Update the ip string
ip = to_string(octets_int) + "." + to_string(octets_int) + "." +
to_string(octets_int) + "." + to_string(octets_int);

// Update the number of IP addresses we need to cover
n -= bits;
}

return result;
}
};```
```using System;

public class Solution {

public List IpToCIDR(string ip, int n) {

// TODO: Implement your solution here

}

}```
Scroll to Top

## Top 100 Leetcode Practice Problems In Java

Get 30% Off Instantly!
[gravityforms id="5" description="false" titla="false" ajax="true"]