123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- package geodb
- import (
- "fmt"
- "net"
- "strconv"
- "strings"
- )
- type trie_Node struct {
- childrens [2]*trie_Node
- ends bool
- cc string
- }
- // Initializing the root of the trie
- type trie struct {
- root *trie_Node
- }
- func ipToBitString(ip string) string {
- // Parse the IP address string into a net.IP object
- parsedIP := net.ParseIP(ip)
- // Convert the IP address to a 4-byte slice
- ipBytes := parsedIP.To4()
- // Convert each byte in the IP address to its 8-bit binary representation
- var result []string
- for _, b := range ipBytes {
- result = append(result, fmt.Sprintf("%08b", b))
- }
- // Join the binary representation of each byte with dots to form the final bit string
- return strings.Join(result, "")
- }
- func bitStringToIp(bitString string) string {
- // Split the bit string into four 8-bit segments
- segments := []string{
- bitString[:8],
- bitString[8:16],
- bitString[16:24],
- bitString[24:32],
- }
- // Convert each segment to its decimal equivalent
- var decimalSegments []int
- for _, s := range segments {
- i, _ := strconv.ParseInt(s, 2, 64)
- decimalSegments = append(decimalSegments, int(i))
- }
- // Join the decimal segments with dots to form the IP address string
- return fmt.Sprintf("%d.%d.%d.%d", decimalSegments[0], decimalSegments[1], decimalSegments[2], decimalSegments[3])
- }
- // inititlaizing a new trie
- func newTrie() *trie {
- t := new(trie)
- t.root = new(trie_Node)
- return t
- }
- // Passing words to trie
- func (t *trie) insert(ipAddr string, cc string) {
- word := ipToBitString(ipAddr)
- current := t.root
- for _, wr := range word {
- index := wr - '0'
- if current.childrens[index] == nil {
- current.childrens[index] = &trie_Node{
- childrens: [2]*trie_Node{},
- ends: false,
- cc: cc,
- }
- }
- current = current.childrens[index]
- }
- current.ends = true
- }
- func isReservedIP(ip string) bool {
- parsedIP := net.ParseIP(ip)
- if parsedIP == nil {
- return false
- }
- // Check if the IP address is a loopback address
- if parsedIP.IsLoopback() {
- return true
- }
- // Check if the IP address is in the link-local address range
- if parsedIP.IsLinkLocalUnicast() || parsedIP.IsLinkLocalMulticast() {
- return true
- }
- // Check if the IP address is in the private address ranges
- privateRanges := []*net.IPNet{
- {IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)},
- {IP: net.ParseIP("172.16.0.0"), Mask: net.CIDRMask(12, 32)},
- {IP: net.ParseIP("192.168.0.0"), Mask: net.CIDRMask(16, 32)},
- }
- for _, r := range privateRanges {
- if r.Contains(parsedIP) {
- return true
- }
- }
- // If the IP address is not a reserved address, return false
- return false
- }
- // Initializing the search for word in node
- func (t *trie) search(ipAddr string) string {
- if isReservedIP(ipAddr) {
- return ""
- }
- word := ipToBitString(ipAddr)
- current := t.root
- for _, wr := range word {
- index := wr - '0'
- if current.childrens[index] == nil {
- return current.cc
- }
- current = current.childrens[index]
- }
- if current.ends {
- return current.cc
- }
- //Not found
- return ""
- }
|