mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-08-07 05:38:30 +02:00
v2 init commit
This commit is contained in:
131
src/mod/geodb/trie.go
Normal file
131
src/mod/geodb/trie.go
Normal file
@@ -0,0 +1,131 @@
|
||||
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 ""
|
||||
}
|
Reference in New Issue
Block a user