Skip to content

Instantly share code, notes, and snippets.

@ecnepsnai
Last active April 3, 2025 21:36
Show Gist options
  • Save ecnepsnai/5fe93f90f3c0ae5421c56a3c44096d47 to your computer and use it in GitHub Desktop.
Save ecnepsnai/5fe93f90f3c0ae5421c56a3c44096d47 to your computer and use it in GitHub Desktop.
Deduplicate an list of CIDR subnets
// Command uniquenet takes a file containing a list of CIDR-notated subnets and returns a de-duplicated list.
// Deduplication is more than just literal duplicates, it also takes into consideration if a subnet is fully represented
// by another larger subnet in the list.
//
// Usage: uniquenet [-6] <File path>
// By default, uniquenet only returns a list of IPv4 subnets. Pass -6 to switch to IPv6 only.
// File path must be a text file where each line contains only a CIDR address, that is a network address '/' prefix
// length.
package main
import (
"bufio"
"fmt"
"net"
"os"
"strings"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, fmt.Sprintf("Usage: %s [-6] <File path>", os.Args[0]))
os.Exit(1)
}
var filePath string
var includeV4 = true
var includeV6 = false
for _, arg := range os.Args[1:] {
if arg == "-6" {
includeV4 = false
includeV6 = true
} else {
filePath = arg
}
}
f, err := os.Open(filePath)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
defer f.Close()
subnets := []net.IPNet{}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
_, net, err := net.ParseCIDR(line)
if err != nil {
fmt.Fprintln(os.Stderr, fmt.Sprintf("Invalid line '%s': %s", line, err.Error()))
os.Exit(1)
}
isV6 := strings.Contains(line, ":")
if (!isV6 && includeV4) || (isV6 && includeV6) {
subnets = append(subnets, *net)
}
}
netMap := map[string]int{}
for _, subnet := range subnets {
netStr := subnet.String()
for _, otherSubnet := range subnets {
otherNetStr := otherSubnet.String()
if netStr == otherNetStr {
continue
}
if otherSubnet.Contains(subnet.IP) {
v := netMap[netStr]
v++
netMap[netStr] = v
}
}
}
for i := len(subnets) - 1; i >= 0; i-- {
netStr := subnets[i].String()
if netMap[netStr] > 0 {
subnets = append(subnets[:i], subnets[i+1:]...)
}
}
for _, subnet := range subnets {
fmt.Println(subnet.String())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment