trie.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package geodb
  2. import (
  3. "net"
  4. )
  5. type trie_Node struct {
  6. childrens [2]*trie_Node
  7. cc string
  8. }
  9. // Initializing the root of the trie
  10. type trie struct {
  11. root *trie_Node
  12. }
  13. func ipToInt64(ip string) int64 {
  14. // Parse the IP address string into a net.IP object
  15. parsedIP := net.ParseIP(ip)
  16. // Convert the IP address to a 4-byte slice
  17. ipBytes := parsedIP.To4()
  18. if ipBytes == nil {
  19. //This is an IPv6 address
  20. ipBytes = parsedIP.To16()
  21. }
  22. // Convert each byte in the IP address to its 8-bit binary representation
  23. var ipInt64 int64
  24. for _, b := range ipBytes {
  25. ipInt64 <<= 8
  26. ipInt64 |= int64(b)
  27. }
  28. // Join the binary representation of each byte with dots to form the final bit string
  29. return ipInt64
  30. }
  31. // inititlaizing a new trie
  32. func newTrie() *trie {
  33. t := new(trie)
  34. t.root = new(trie_Node)
  35. return t
  36. }
  37. // Passing words to trie
  38. func (t *trie) insert(ipAddr string, cc string) {
  39. ipInt64 := ipToInt64(ipAddr)
  40. current := t.root
  41. for i := 63; i >= 0; i-- {
  42. bit := (ipInt64 >> uint(i)) & 1
  43. if current.childrens[bit] == nil {
  44. current.childrens[bit] = &trie_Node{
  45. childrens: [2]*trie_Node{},
  46. cc: cc,
  47. }
  48. }
  49. current = current.childrens[bit]
  50. }
  51. }
  52. func isReservedIP(ip string) bool {
  53. parsedIP := net.ParseIP(ip)
  54. if parsedIP == nil {
  55. return false
  56. }
  57. // Check if the IP address is a loopback address
  58. if parsedIP.IsLoopback() {
  59. return true
  60. }
  61. // Check if the IP address is in the link-local address range
  62. if parsedIP.IsLinkLocalUnicast() || parsedIP.IsLinkLocalMulticast() {
  63. return true
  64. }
  65. if parsedIP.IsPrivate() {
  66. return true
  67. }
  68. // If the IP address is not a reserved address, return false
  69. return false
  70. }
  71. // Initializing the search for word in node
  72. func (t *trie) search(ipAddr string) string {
  73. if isReservedIP(ipAddr) {
  74. return ""
  75. }
  76. ipInt64 := ipToInt64(ipAddr)
  77. current := t.root
  78. for i := 63; i >= 0; i-- {
  79. bit := (ipInt64 >> uint(i)) & 1
  80. if current.childrens[bit] == nil {
  81. return current.cc
  82. }
  83. current = current.childrens[bit]
  84. }
  85. if len(current.childrens) == 0 {
  86. return current.cc
  87. }
  88. //Not found
  89. return ""
  90. }