package utils import ( "fmt" "log" "net" "strings" "sync" "github.com/lionsoul2014/ip2region/binding/golang/xdb" ) var ( searcher *xdb.Searcher once sync.Once ) // InitIP2Region 初始化 ip2region // 需要 ip2region.xdb 文件,如果不存在则仅支持基本IP解析 func InitIP2Region(dbPath string) { once.Do(func() { var err error // 1. 尝试加载整个xdb到内存,性能最好 cBuff, err := xdb.LoadContentFromFile(dbPath) if err != nil { log.Printf("Failed to load ip2region.xdb: %v. Region lookup will be disabled.", err) return } searcher, err = xdb.NewWithBuffer(cBuff) if err != nil { log.Printf("Failed to create searcher: %v", err) return } log.Println("IP2Region loaded successfully") }) } // GetRegion 获取IP归属地 // 返回格式: 国家|区域|省份|城市|ISP func GetRegion(ip string) string { if searcher == nil { return "Unknown" } // 过滤内网IP if isPrivateIP(ip) { return "Internal" } region, err := searcher.SearchByStr(ip) if err != nil { return "Unknown" } return region } // 简单判断内网IP func isPrivateIP(ipStr string) bool { ip := net.ParseIP(ipStr) if ip == nil { return false // 不是有效IP } if ip.IsLoopback() { return true } ip4 := ip.To4() if ip4 == nil { return false // 暂不处理IPv6内网判断 } return ip4[0] == 10 || (ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31) || (ip4[0] == 192 && ip4[1] == 168) }