# 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:

- 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”.

- 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.

- 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.

- 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 (subnet mask)
- 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
mask = 1
while mask < n:
mask *= 2
mask -= 1
# Calculate the prefix length
prefix_len = 0
while mask > 0:
mask //= 2
prefix_len += 1
# Add the CIDR block to the list
blocks.append(ip_num_to_ip_str(ip_num) + '/' + str(32 - prefix_len))
# Update the IP address and the number of addresses remaining
ip_num += mask + 1
n -= mask + 1
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 ListipToCidr(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 cidrs.add(longToIp(ip) + "/" + getCidrPrefix(numAllocatedIps)); // 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[4]; for (int i = 0; i < 4; i++) { octets[i] = (int) (ip >> ((3 - i) * 8)) & 0xFF; } // Join the octets together with periods return octets[0] + "." + octets[1] + "." + octets[2] + "." + octets[3]; } /** * 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: vectoripToCIDR(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 // address 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--; } // Add the current IP address to the result 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[0]) + "." + to_string(octets_int[1]) + "." + to_string(octets_int[2]) + "." + to_string(octets_int[3]); // Update the number of IP addresses we need to cover n -= bits; } return result; } };

using System; public class Solution { public ListIpToCIDR(string ip, int n) { // TODO: Implement your solution here } }