func (h *IPRangeHolder) FindCountry(ip string) (string, error) { v, err := util.IPv42Int(ip) if nil != err { log.Printf("Failed to convert ip to int for reason:%v\n", err) return "", err } compare := func(i int) bool { return h.ranges[i].Start > uint64(v) || h.ranges[i].Start <= uint64(v) && h.ranges[i].End >= uint64(v) } index := sort.Search(len(h.ranges), compare) if index == len(h.ranges) { return "", nil } if index > 0 { if h.ranges[index].Start > uint64(v) || h.ranges[index].End < uint64(v) { return "", nil } return h.ranges[index].Country, nil } return "", fmt.Errorf("No record found.") }
func ParseApnic(name string) (*IPRangeHolder, error) { var file *os.File var err error if file, err = os.Open(name); err != nil { return nil, err } reader := bufio.NewReader(file) var buffer bytes.Buffer var ( part []byte prefix bool ) holder := new(IPRangeHolder) for { if part, prefix, err = reader.ReadLine(); err != nil { break } buffer.Write(part) if !prefix { line := buffer.String() buffer.Reset() sp := strings.Split(line, "|") if len(sp) >= 6 { if sp[1] == "CN" && sp[2] == "ipv4" { startip, _ := util.IPv42Int(sp[3]) ipcount, _ := strconv.ParseUint(sp[4], 10, 32) tmp := &IPRange{uint64(startip), uint64(startip) + uint64(ipcount-1), sp[1]} holder.ranges = append(holder.ranges, tmp) } } } } file.Close() holder.sort() return holder, nil }