35 lines
988 B
Text
35 lines
988 B
Text
local fmt = require "fmt"
|
|
|
|
-- Canonicalize a CIDR block: make sure none of the host bits are set.
|
|
local function canonicalize(cidr)
|
|
-- Dotted-decimal / bits in network part.
|
|
local split = cidr:split("/")
|
|
local dotted = split[1]
|
|
local size = tonumber(split[2])
|
|
|
|
-- Get IP as binary string.
|
|
local binary = dotted:split("."):map(|n| -> fmt.lpad(fmt.bin(tonumber(n)), 8, "0")):concat()
|
|
|
|
-- Replace the host part with all zeros.
|
|
binary = binary:sub(1, size) .. string.rep("0", 32 - size)
|
|
|
|
-- Convert back to dotted-decimal.
|
|
local chunks = binary:split(""):chunk(8):map(|c| -> c:concat())
|
|
local canon = chunks:map(|c| -> tonumber(c, 2)):concat(".")
|
|
|
|
-- And return
|
|
return canon .. "/" .. split[2]
|
|
end
|
|
|
|
local tests = {
|
|
"87.70.141.1/22",
|
|
"36.18.154.103/12",
|
|
"62.62.197.11/29",
|
|
"67.137.119.181/4",
|
|
"161.214.74.21/24",
|
|
"184.232.176.184/18"
|
|
}
|
|
|
|
for tests as test do
|
|
fmt.print("%-18s -> %s", test, canonicalize(test))
|
|
end
|