Subnet in Supernet?

There was a relevance challenge a while back for calculating if an IP is inside of a given subrnet (useful for computer grouping by CIDR ranges). You can also test subnets for supernet membership using the same bit level comparisons.

All of the solutions were for IPv4. Yesterday someone joked about how hard the IPv6 version might be. Turns out it is not really that different. You still convert to bits, but you need to do a hex convert instead of an integer convert, and you need to grab 16 bits of length instead of 8 and you separate at the : instead of the .. Other than those things, it is the same problem

q: first (following text of first "/" of it as integer) of (concatenation of (last 8 of padded string of (it as integer as bit set)) of substrings separated by "." of preceding text of first "/" of it & "/" & following text of first "/" of it) of ("192.168.0.0/24")
A: 110000001010100000000000
T: 1.447 ms
I: singular substring

vs

q: first (following text of first "/" of it as integer) of (concatenation of (last 16 of padded string of  (hexadecimal integer (it) as bits)) of substrings separated by ":" of preceding text of first "/" of it & "/" &  following text of first "/" of it) of "2001:0DB9:AC10:FE01:0000:0000:0000:0000/64"
A: 0010000000000001000011011011100110101100000100001111111000000001
1 Like

And testing for matches, you just use it twice and check “starts with”.
(It even works with the omitted :0000 form of CIDR for ipv6)

q: (((first (following text of first "/" of it as integer) of ((concatenation of (last 16 of padded string of  (hexadecimal integer (it) as bits)) of substrings separated by ":" whose (exists hexadecimal integer (it)) of preceding text of first "/" of it) & "/" &  following text of first "/" of it)) of ("2001:0DB9:AC10:FE01:0000:0000:0000:0000/64")),((first (following text of first "/" of it as integer) of ((concatenation of (last 16 of padded string of  (hexadecimal integer (it) as bits)) of substrings separated by ":" whose (exists hexadecimal integer (it)) of preceding text of first "/" of it) & "/" &  following text of first "/" of it)) of ("2001:0DB8/31";"2001:0DB8:/32"))) whose (item 0 of it starts with item 1 of it)
A: 0010000000000001000011011011100110101100000100001111111000000001, 0010000000000001000011011011100

Only the larger /31 subnet matches.

2001:0DB9:AC10:FE01:0000:0000:0000:0000/64 is a member of 2001:0DB8/31
2001:0DB9:AC10:FE01:0000:0000:0000:0000/64 is not a member of 2001:0DB8/32

3 Likes