Convert IPv4 Ranges to CIDR Blocks
Company: OpenAI
Role: Backend Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Implement a function that summarizes a consecutive IPv4 address range using the smallest possible list of CIDR blocks.
You are given:
- `start_ip`: a valid IPv4 address string such as `"192.168.0.7"`.
- `count`: a positive integer representing how many consecutive addresses must be covered, starting exactly at `start_ip`.
Return a list of CIDR block strings that cover exactly the addresses from `start_ip` through the next `count - 1` addresses, without including any address before `start_ip` or after the range.
A CIDR block has the form `a.b.c.d/prefix`, where `prefix` is between 0 and 32. For example, `"192.168.0.8/29"` represents 8 addresses starting at `192.168.0.8`.
Requirements:
1. Treat IPv4 addresses as unsigned 32-bit values.
2. At each step, choose a block that starts at the current address, is correctly aligned for its size, and does not exceed the remaining range.
3. Return a minimal-length list of CIDR blocks.
4. Include unit tests for edge cases such as a single address, unaligned starts, ranges crossing octet boundaries, and ranges ending near `255.255.255.255`.
Example:
Input:
```text
start_ip = "255.0.0.7"
count = 10
```
Output:
```text
[
"255.0.0.7/32",
"255.0.0.8/29",
"255.0.0.16/32"
]
```
Explanation: The output covers exactly 10 addresses starting at `255.0.0.7`. It must not round the first block down to an earlier network boundary, because that would include addresses before the input address.
Quick Answer: This question evaluates understanding of IPv4 addressing, binary/bitwise manipulation, and the ability to summarize consecutive address ranges into minimal CIDR blocks, and belongs to the Coding & Algorithms domain for backend engineering roles.
Implement a function that summarizes a consecutive IPv4 address range using the smallest possible list of CIDR blocks.
You are given a starting IPv4 address string `start_ip` and a positive integer `count`. Return a list of CIDR block strings that covers exactly the `count` consecutive addresses starting at `start_ip`, without including any address before or after the range.
A CIDR block has the form `a.b.c.d/prefix`, where the block size is `2^(32 - prefix)`. Each block you choose must:
- start exactly at the current address being covered,
- be correctly aligned for its size,
- and not exceed the remaining number of addresses.
Your goal is to return a minimal-length list of CIDR blocks.
For example, if `start_ip = "255.0.0.7"` and `count = 10`, the correct result is:
`["255.0.0.7/32", "255.0.0.8/29", "255.0.0.16/32"]`
because the first address is unaligned, so you cannot round down to an earlier network boundary.
Constraints
- `start_ip` is a valid IPv4 address with 4 octets in the range 0 to 255
- `1 <= count <= 2^32`
- The range from `start_ip` through the next `count - 1` addresses stays within `0.0.0.0` to `255.255.255.255`
- Treat IPv4 addresses as unsigned 32-bit integers
Examples
Input: ("255.0.0.7", 10)
Expected Output: ["255.0.0.7/32", "255.0.0.8/29", "255.0.0.16/32"]
Explanation: Address 255.0.0.7 is not aligned to any larger block, so it must be a /32. Then 255.0.0.8 through 255.0.0.15 fits in a /29, and the final address 255.0.0.16 is another /32.
Input: ("0.0.0.0", 1)
Expected Output: ["0.0.0.0/32"]
Explanation: A single address is always represented as a /32 block.
Input: ("0.0.0.0", 8)
Expected Output: ["0.0.0.0/29"]
Explanation: Starting at 0.0.0.0, the range of 8 addresses is perfectly aligned, so one /29 block is minimal.
Input: ("192.168.1.5", 3)
Expected Output: ["192.168.1.5/32", "192.168.1.6/31"]
Explanation: 192.168.1.5 must stand alone. The remaining two addresses, 192.168.1.6 and 192.168.1.7, form one aligned /31 block.
Input: ("10.0.0.254", 4)
Expected Output: ["10.0.0.254/31", "10.0.1.0/31"]
Explanation: The first two addresses are 10.0.0.254 and 10.0.0.255, which fit in a /31. The next two are 10.0.1.0 and 10.0.1.1, another /31, crossing the octet boundary exactly.
Input: ("255.255.255.252", 4)
Expected Output: ["255.255.255.252/30"]
Explanation: The four addresses 255.255.255.252 through 255.255.255.255 form one aligned /30 block near the upper end of the IPv4 space.
Hints
- Convert the IPv4 address into a 32-bit integer so the range becomes a simple interval of numbers.
- At each step, the largest aligned block starting at the current address is determined by its lowest set bit; then shrink that block if it would exceed the remaining address count.