Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.os.linux.misc > #86000
| From | Fritz Wuehler <fritz@spamexpire-202604.rodent.frell.theremailer.net> |
|---|---|
| Subject | Re: CIDR Calculator |
| References | <XnsB43B9C55314F7makowiecatnycapdotrE@157.180.91.226> |
| Message-ID | <230682093e8d6870b570336706434104@msgid.frell.theremailer.net> (permalink) |
| Date | 2026-04-29 00:08 +0200 |
| Newsgroups | comp.os.linux.misc |
| Organization | dizum.com - The Internet Problem Provider |
Joe Makowiec <makow...@invalid.invalid> [JM]:
JM> What I'm looking for, though, is one where you can feed it a
JM> low IP address and a high IP address, and it will figure out
JM> the (singular) range which covers all the IP addresses.
Here is a LLM-generated plain C and javascript/nodejs such
function. Take your pick.
// 8<---------------------------- C -------------------------
/*
* findMinimumCIDR.c
*
* Build the smallest single CIDR block that contains two IPv4 addresses.
*
* Example:
* 192.168.0.8 and 192.168.5.200 -> 192.168.0.0/21
*
* Build:
* cc -O2 -Wall -Wextra -std=c11 findMinimumCIDR.c -o findMinimumCIDR
*
* Run:
* ./findMinimumCIDR 192.168.0.8 192.168.5.200
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
static int parse_ipv4(const char *s, uint32_t *out)
{
unsigned a, b, c, d;
char tail;
/* Ensure full-string match (no trailing junk) */
if (sscanf(s, "%u.%u.%u.%u%c", &a, &b, &c, &d, &tail) != 4)
return 0;
if (a > 255 || b > 255 || c > 255 || d > 255)
return 0;
*out = (a << 24) | (b << 16) | (c << 8) | d;
return 1;
}
static void ipv4_to_str(uint32_t ip, char buf[16])
{
snprintf(buf, 16, "%u.%u.%u.%u",
(ip >> 24) & 255u, (ip >> 16) & 255u, (ip >> 8) & 255u, ip & 255u);
}
static unsigned prefix_len_for_range(uint32_t a, uint32_t b)
{
uint32_t x = a ^ b; /* differing bits */
unsigned common = 32;
if (x != 0) {
/* count leading zeros in x (portable loop) */
common = 0;
for (int i = 31; i >= 0; --i) {
if ((x >> i) & 1u) break;
common++;
}
}
return common; /* number of equal leading bits => CIDR prefix length */
}
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "Usage: %s <ipv4_1> <ipv4_2>\n", argv[0]);
return 2;
}
uint32_t ip1, ip2;
if (!parse_ipv4(argv[1], &ip1) || !parse_ipv4(argv[2], &ip2)) {
fprintf(stderr, "Invalid IPv4 address.\n");
return 2;
}
unsigned prefix = prefix_len_for_range(ip1, ip2);
uint32_t mask = (prefix == 0) ? 0u : (0xFFFFFFFFu << (32 - prefix));
uint32_t network = ip1 & mask; /* ip1 and ip2 share these prefix bits */
char netstr[16];
ipv4_to_str(network, netstr);
printf("%s/%u\n", netstr, prefix);
return 0;
}
// 8<--------------------- javascript/nodejs ----------------
/* How it works:
1. IP to Integer Conversion: Converts each IPv4 address to a 32-bit integer for bitwise operations.
2. XOR Operation: Uses XOR (`^`) to find where the two IP addresses differ in their binary representation.
3. Prefix Length Calculation: Counts the number of leading bits that are the same in both addresses by examining the XOR result.
4. Network Address Calculation: Creates a network mask and applies it to find the network address.
5. CIDR Format: Returns the result in CIDR notation (network/prefix-length).
Example walkthrough with `192.168.0.8` and `192.168.5.200`:
- 192.168.0.8 = 11000000.10101000.00000000.00001000
- 192.168.5.200 = 11000000.10101000.00000101.11001000
- XOR result shows differences starting at bit 21
- First 21 bits are common, so prefix length is 21
- Network address: `192.168.0.0/21`
The function handles the parameters in any order and will always return the same CIDR range regardless of which IP is passed first.
*/
function findMinimumCIDR(ip1, ip2) {
// Convert IP address string to 32-bit integer
function ipToInt(ip) {
return ip.split('.').reduce((acc, octet, index) => {
return acc + (parseInt(octet) << (8 * (3 - index)));
}, 0) >>> 0; // Use unsigned right shift to ensure positive integer
}
// Convert 32-bit integer back to IP address string
function intToIp(int) {
return [
(int >>> 24) & 255,
(int >>> 16) & 255,
(int >>> 8) & 255,
int & 255
].join('.');
}
// Convert both IPs to integers
const int1 = ipToInt(ip1);
const int2 = ipToInt(ip2);
// Find the XOR to see where bits differ
const xor = int1 ^ int2;
// Count leading zeros in the XOR result to find common prefix length
let prefixLength = 0;
let mask = 0x80000000; // Start with leftmost bit
for (let i = 0; i < 32; i++) {
if ((xor & mask) === 0) {
prefixLength++;
mask >>>= 1;
} else {
break;
}
}
// Create network mask
const networkMask = (0xFFFFFFFF << (32 - prefixLength)) >>> 0;
// Calculate network address (use the smaller IP for consistency)
const networkAddress = Math.min(int1, int2) & networkMask;
return `${intToIp(networkAddress)}/${prefixLength}`;
}
// Testing
console.log(findMinimumCIDR('192.168.0.8', '192.168.5.200')); // 192.168.0.0/21
console.log(findMinimumCIDR('192.168.5.200', '192.168.0.8')); // 192.168.0.0/21
// Additional test cases
console.log(findMinimumCIDR('10.0.0.1', '10.0.0.2')); // 10.0.0.0/30
console.log(findMinimumCIDR('192.168.1.1', '192.168.1.1')); // 192.168.1.1/32
console.log(findMinimumCIDR('172.16.0.1', '172.17.255.254')); // 172.16.0.0/15
Back to comp.os.linux.misc | Previous | Next — Previous in thread | Next in thread | Find similar
CIDR Calculator Joe Makowiec <makowiec@invalid.invalid> - 2026-04-27 19:22 +0000
Re: CIDR Calculator John Ames <commodorejohn@gmail.com> - 2026-04-27 13:31 -0700
Re: CIDR Calculator Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-04-29 01:59 +0000
Re: CIDR Calculator Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-04-27 22:35 +0000
Re: CIDR Calculator Marc Haber <mh+usenetspam2616@zugschl.us> - 2026-04-28 07:49 +0200
Re: CIDR Calculator Rene Kita <mail@rkta.de> - 2026-04-29 07:09 +0000
Re: CIDR Calculator Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-04-29 08:05 +0000
Re: CIDR Calculator Fritz Wuehler <fritz@spamexpire-202604.rodent.frell.theremailer.net> - 2026-04-29 00:08 +0200
Re: CIDR Calculator 🇵🇱Jacek Marcin Jaworski🇵🇱 <jmj@energokod.gda.pl> - 2026-04-29 07:10 +0200
Re: CIDR Calculator 🇵🇱Jacek Marcin Jaworski🇵🇱 <jmj@energokod.gda.pl> - 2026-04-29 23:52 +0200
csiph-web