mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-06 23:57:21 +02:00
106 lines
2.0 KiB
Go
106 lines
2.0 KiB
Go
package geodb
|
|
|
|
import (
|
|
"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 (4 / 16 bytes)
|
|
//each byte is 8 bit
|
|
for j := 7; j >= 0; j-- {
|
|
bit := int(b >> j & 1)
|
|
if current.childrens[bit] == nil {
|
|
current.childrens[bit] = &trie_Node{
|
|
childrens: [2]*trie_Node{},
|
|
cc: cc,
|
|
}
|
|
}
|
|
current = current.childrens[bit]
|
|
}
|
|
}
|
|
}
|
|
|
|
// isReservedIP check if the given ip address is NOT a public ip address
|
|
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 is in the reserved private range
|
|
if parsedIP.IsPrivate() {
|
|
return true
|
|
}
|
|
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 := 7; j >= 0; j-- {
|
|
bit := int(b >> j & 1)
|
|
if current.childrens[bit] == nil {
|
|
return current.cc
|
|
}
|
|
current = current.childrens[bit]
|
|
}
|
|
}
|
|
|
|
if len(current.childrens) == 0 {
|
|
return current.cc
|
|
}
|
|
|
|
//Not found
|
|
return ""
|
|
}
|