Get geographic location information based on IP – Golang

Get geographic location information based on IP – Golang

  • 1 Introduction
    • 1.1 ip2region
    • 1.2 geoip2-golang
    • 1.3 Summary
  • 2 use
    • 2.1 ip2region
    • 2.2 geoip2-golang

1 Introduction

1 ip2region
2 geoip2-golang

1.1 ip2region

ip2region is an offline IP address location library and IP location data management framework, with a query efficiency of 10 microseconds, and provides xdb data generation and query client implementations in many mainstream programming languages.

Features:

  1. is an open source IP geolocation library.
  2. standardized data format
    The region information of each ip data segment has a fixed format: Country|Region|Province|City|ISP, only most of the data in China is accurate to the city, and some data in other countries can only be located in the country, and the options before and after are all 0.
  3. Data deduplication and compression
  4. Extremely fast query response
    Even for queries based entirely on xdb files, the response time for a single query is at the level of ten microseconds.
  5. IP Data Management Framework

shortcoming:
ip2region focuses on researching the storage of IP data and the realization of fast query, without the support of original IP data, this project does not guarantee timely data update, there will be no commercial version for the time being.

1.2 geoip2-golang

geoip2-golang is just a usage example, the IP geographic information library it needs is based on GeoLite2 and GeoIP2 provided by MaxMind code> database.

Features:

  1. maxmind provides a free local deployable geo-ip database (GeoLite2) (mmdb and csv format), and geo-ip query api service.
  2. Support geographic information query of ipv4 and ipv6, and ASN database (ip-operator information query)
  3. The free database updates every two weeks, and you need to pay to get the fastest update speed.

1.3 Summary

It is recommended to use geoip2-golang first, followed by ip2region. If you need more precision, it is recommended to choose a commercial one.

2 use

2.1 ip2region

  1. Download the ip address library
    Go to github: https://github.com/lionsoul2014/ip2region to download the code.

  2. ip2region library
    ip2region.xdb under data

  3. use

package main

import (
"fmt"
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
"net"
"time"
)

func main() {<!-- -->
ip2region()
}
func ip2region() {<!-- -->
var dbPath = "iputil/ip2region/ip2region.xdb"
searcher, err := xdb. NewWithFileOnly(dbPath)
if err != nil {<!-- -->
fmt.Printf("failed to create searcher: %s\\
", err.Error())
return
}

defer searcher. Close()
var ip = "115.223.9.122"
var tStart = time. Now()
ips, err := net.LookupIP("www.github.com")
ipres := ips[0].String()
fmt.Printf("IP of domain name: %s\\
", ipres)
region, err := searcher.SearchByStr(ip)
if err != nil {<!-- -->
fmt.Printf("failed to SearchIP(%s): %s\\
", ip, err)
return
}
fmt.Printf("{region: %s, took: %s}\\
\\
", region, time.Since(tStart))
// Remarks: For concurrent use, each goroutine needs to create an independent searcher object.
}

result:

IP of the domain name: 20.205.243.166
{<!-- -->region: China|0|Zhejiang|Wenzhou|Telecom, took: 70.8846ms}

2.2 geoip2-golang

geoip2-golang is just a usage example, the IP geographic information library it needs is based on GeoLite2 and GeoIP2 provided by MaxMind code> database. So you need to go to the MAXMID official website to register an account, and then you can download the latest IP geolocation library.

  1. register
    Address: https://www.maxmind.com/en/geolite2/signup, no real information is required except email.
  2. Log in
  3. Download the latest IP geolocation library
    After logging in, click Download Databases to enter the download selection page
  4. Download library file
    maxmind provides six free databases, including mmdb [recommended] and csv format. You can also download them all.

ASN database
It can be seen from the figure that the title of some databases is followed by the three letters “ASN”. This ASN refers to the database of ip-operator information.

mmdb database
mmdb is a binary database format of maxmind, which provides faster ip query speed.

Here we only download library files that are not in CSV format, that is, only download the ones circled in red, and the download button is on the right.

Note: MAXMIND will record downloads, so do not download repeatedly to avoid being banned.

  1. Library file
  • GeoLite2-ASN_20230505.tar.gz
  • GeoLite2-City_20230505.tar.gz
  • GeoLite2-Country_20230505.tar.gz

After decompression, they are all mmdb database types, please test the specific differences by yourself.

  1. use
  • Download geoip2-golang
go get github.com/oschwald/geoip2-golang

Code example:

package main

import (
"fmt"
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
"github.com/oschwald/geoip2-golang"
"log"
"net"
"time"
)

func main() {<!-- -->
ip2region()
geoip()
}
func ip2region() {<!-- -->
var dbPath = "iputil/ip2region/ip2region.xdb"
searcher, err := xdb. NewWithFileOnly(dbPath)
if err != nil {<!-- -->
fmt.Printf("failed to create searcher: %s\\
", err.Error())
return
}

defer searcher. Close()
var ip = "115.223.9.122"
var tStart = time. Now()
ips, err := net.LookupIP("www.github.com")
ipres := ips[0].String()
fmt.Printf("IP of domain name: %s\\
", ipres)
region, err := searcher.SearchByStr(ip)
if err != nil {<!-- -->
fmt.Printf("failed to SearchIP(%s): %s\\
", ip, err)
return
}
fmt.Printf("{region: %s, took: %s}\\
\\
", region, time.Since(tStart))
// Remarks: For concurrent use, each goroutine needs to create an independent searcher object.
}

func geoip() {<!-- -->
db, err := geoip2.Open("iputil/geolite2/GeoLite2-City.mmdb")
if err != nil {<!-- -->
log. Fatal(err)
}
defer db. Close()
// If you are using strings that may be invalid, check that ip is not nil
//ip := net.ParseIP("81.2.69.142")
ip := net.ParseIP("115.192.211.101")
record, err := db. City(ip)
if err != nil {<!-- -->
log. Fatal(err)
}
fmt.Printf("Portuguese (BR) city name: %v\\
", record.City.Names["pt-BR"])
if len(record. Subdivisions) > 0 {<!-- -->
fmt.Printf("English subdivision name: %v\\
", record.Subdivisions[0].Names["en"])
}
fmt.Printf("Russian country name: %v\\
", record.Country.Names["ru"])
fmt.Printf("ISO country code: %v\\
", record.Country.IsoCode)
fmt.Printf("Time zone: %v\\
", record.Location.TimeZone)
fmt.Printf("Coordinates: %v, %v\\
", record.Location.Latitude, record.Location.Longitude)
//Output:
// Portuguese (BR) city name: Londres
// English subdivision name: England
// Russian country name: Великобритания
// ISO country code: GB
// Time zone: Europe/London
// Coordinates: 51.5142, -0.0931

fmt.Println("Chinese result")
fmt.Printf("Portuguese (BR) city name: %v\\
", record.City.Names["zh-CN"])
if len(record. Subdivisions) > 0 {<!-- -->
fmt.Printf("English subdivision name: %v\\
", record.Subdivisions[0].Names["zh-CN"])
}
fmt.Printf("Russian country name: %v\\
", record.Country.Names["zh-CN"])
fmt.Printf("ISO country code: %v\\
", record.Country.IsoCode)
fmt.Printf("Time zone: %v\\
", record.Location.TimeZone)
fmt.Printf("Coordinates: %v, %v\\
", record.Location.Latitude, record.Location.Longitude)
}

result:

Portuguese (BR) city name: Hangzhou
English subdivision name: Zhejiang
Russian country name: Китай
ISO country code: CN
Time zone: Asia/Shanghai
Coordinates: 30.2994, 120.1612
Chinese result
Portuguese (BR) city name: Hangzhou
English subdivision name: Zhejiang Province
Russian country name: China
ISO country code: CN
Time zone: Asia/Shanghai
Coordinates: 30.2994, 120.1612
  1. Change the output to Chinese
    Just change Names[“en”] to Names[“zh-CN”] to display Chinese.