IPBinarySet is a fast and memory-efficient data structure for storing and querying IP address ranges
| .gitignore | ||
| example_test.go | ||
| go.mod | ||
| ipbinaryset.go | ||
| ipbinaryset_test.go | ||
| ipv4range.go | ||
| ipv4range_test.go | ||
| ipv6range.go | ||
| ipv6range_test.go | ||
| LICENSE | ||
| README.md | ||
| uint128.go | ||
| uint128_test.go | ||
ipbinaryset
IPBinarySet is a fast and memory-efficient data structure for storing and querying IP address ranges. It maintains a sorted, merged list of IPv4 and IPv6 CIDR prefixes, making it ideal for IP blocklists, allowlists, and other IP filtering applications.
The set uses binary search for O(log n) lookup performance and automatically merges overlapping or contained ranges to minimize memory usage and maintain optimal query speed. IPv4 and IPv6 addresses are stored separately in their respective (mostly optimized) formats.
Installation
go get git.vixen.computer/lua/ipbinaryset
Functions
New()- Create a new empty setAddAddr(addr)- Add a single IP addressAddPrefix(prefix)- Add a CIDR prefixContainsAddr(addr)- Check if an IP is in the setContainsPrefix(prefix)- Check if a prefix is fully containedRemove(prefix)- Remove a prefix from the setAll()- Iterate over all prefixesLen()- Get the number of prefixesCopy()- Get a slice of all prefixesString()- Get string representation of all prefixesUnmarshalText(data)- Parse a newline-delimited list of prefixesMarshalJSON()- Serialize the set as a JSON string arrayUnmarshalJSON(data)- Deserialize the set from a JSON string array
Example
package main
import (
"fmt"
"net/netip"
"git.vixen.computer/lua/ipbinaryset"
)
func main() {
set := ipbinaryset.New()
// Add IP ranges
set.AddPrefix(netip.MustParsePrefix("192.168.0.0/16"))
set.AddPrefix(netip.MustParsePrefix("10.0.0.0/8"))
set.AddPrefix(netip.MustParsePrefix("2001:db8::/32"))
// Add individual addresses
set.AddAddr(netip.MustParseAddr("203.0.113.42"))
// Check if an IP is in the set
if set.ContainsAddr(netip.MustParseAddr("192.168.1.100")) {
fmt.Println("IP is in blocklist")
}
// Iterate over all ranges
for prefix := range set.All() {
fmt.Println(prefix)
}
fmt.Printf("Total ranges: %d\n", set.Len())
}
License
Licensed under the MIT License.
Made with ❤ by Lua (foxgirl.dev).