trie.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package geodb
  2. import (
  3. "fmt"
  4. "net"
  5. "strconv"
  6. "strings"
  7. )
  8. type trie_Node struct {
  9. childrens [2]*trie_Node
  10. ends bool
  11. cc string
  12. }
  13. // Initializing the root of the trie
  14. type trie struct {
  15. root *trie_Node
  16. }
  17. func ipToBitString(ip string) string {
  18. // Parse the IP address string into a net.IP object
  19. parsedIP := net.ParseIP(ip)
  20. // Convert the IP address to a 4-byte slice
  21. ipBytes := parsedIP.To4()
  22. // Convert each byte in the IP address to its 8-bit binary representation
  23. var result []string
  24. for _, b := range ipBytes {
  25. result = append(result, fmt.Sprintf("%08b", b))
  26. }
  27. // Join the binary representation of each byte with dots to form the final bit string
  28. return strings.Join(result, "")
  29. }
  30. func bitStringToIp(bitString string) string {
  31. // Split the bit string into four 8-bit segments
  32. segments := []string{
  33. bitString[:8],
  34. bitString[8:16],
  35. bitString[16:24],
  36. bitString[24:32],
  37. }
  38. // Convert each segment to its decimal equivalent
  39. var decimalSegments []int
  40. for _, s := range segments {
  41. i, _ := strconv.ParseInt(s, 2, 64)
  42. decimalSegments = append(decimalSegments, int(i))
  43. }
  44. // Join the decimal segments with dots to form the IP address string
  45. return fmt.Sprintf("%d.%d.%d.%d", decimalSegments[0], decimalSegments[1], decimalSegments[2], decimalSegments[3])
  46. }
  47. // inititlaizing a new trie
  48. func newTrie() *trie {
  49. t := new(trie)
  50. t.root = new(trie_Node)
  51. return t
  52. }
  53. // Passing words to trie
  54. func (t *trie) insert(ipAddr string, cc string) {
  55. word := ipToBitString(ipAddr)
  56. current := t.root
  57. for _, wr := range word {
  58. index := wr - '0'
  59. if current.childrens[index] == nil {
  60. current.childrens[index] = &trie_Node{
  61. childrens: [2]*trie_Node{},
  62. ends: false,
  63. cc: cc,
  64. }
  65. }
  66. current = current.childrens[index]
  67. }
  68. current.ends = true
  69. }
  70. // Initializing the search for word in node
  71. func (t *trie) search(ipAddr string) string {
  72. word := ipToBitString(ipAddr)
  73. current := t.root
  74. for _, wr := range word {
  75. index := wr - '0'
  76. if current.childrens[index] == nil {
  77. return current.cc
  78. }
  79. current = current.childrens[index]
  80. }
  81. return current.cc
  82. }