123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package geodb
- import (
- "math"
- "net"
- )
- type trie_Node struct {
- childrens [2]*trie_Node
- cc string
- }
- // Initializing the root of the trie
- type trie struct {
- root *trie_Node
- }
- func ipToBytes(ip string) []byte {
- // 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()
- if ipBytes == nil {
- //This is an IPv6 address
- ipBytes = parsedIP.To16()
- }
- return ipBytes
- }
- // 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) {
- ipBytes := ipToBytes(ipAddr)
- current := t.root
- for _, b := range ipBytes {
- //For each byte in the ip address
- //each byte is 8 bit
- for j := 0; j < 8; j++ {
- bitwise := (b&uint8(math.Pow(float64(2), float64(j))) > 0)
- bit := 0b0000
- if bitwise {
- bit = 0b0001
- }
- if current.childrens[bit] == nil {
- current.childrens[bit] = &trie_Node{
- childrens: [2]*trie_Node{},
- cc: cc,
- }
- }
- current = current.childrens[bit]
- }
- }
- /*
- for i := 63; i >= 0; i-- {
- bit := (ipInt64 >> uint(i)) & 1
- if current.childrens[bit] == nil {
- current.childrens[bit] = &trie_Node{
- childrens: [2]*trie_Node{},
- cc: cc,
- }
- }
- current = current.childrens[bit]
- }
- */
- }
- 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
- }
- if parsedIP.IsPrivate() {
- 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 ""
- }
- ipBytes := ipToBytes(ipAddr)
- current := t.root
- for _, b := range ipBytes {
- //For each byte in the ip address
- //each byte is 8 bit
- for j := 0; j < 8; j++ {
- bitwise := (b&uint8(math.Pow(float64(2), float64(j))) > 0)
- bit := 0b0000
- if bitwise {
- bit = 0b0001
- }
- if current.childrens[bit] == nil {
- return current.cc
- }
- current = current.childrens[bit]
- }
- }
- /*
- for i := 63; i >= 0; i-- {
- bit := (ipInt64 >> uint(i)) & 1
- if current.childrens[bit] == nil {
- return current.cc
- }
- current = current.childrens[bit]
- }
- */
- if len(current.childrens) == 0 {
- return current.cc
- }
- //Not found
- return ""
- }
|