{"id":18475063,"url":"https://github.com/pg9182/ip2x","last_synced_at":"2025-10-13T05:32:40.509Z","repository":{"id":64298945,"uuid":"568104770","full_name":"pg9182/ip2x","owner":"pg9182","description":"Idiomatic, efficient, and robust Go library for reading IP2Location databases.","archived":false,"fork":false,"pushed_at":"2023-06-04T17:27:43.000Z","size":112,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-08T13:44:30.190Z","etag":null,"topics":["geolocation","go","ip","ip2location","library"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/pg9182/ip2x","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pg9182.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-11-19T13:19:58.000Z","updated_at":"2024-07-06T23:23:25.000Z","dependencies_parsed_at":"2023-09-26T03:54:59.626Z","dependency_job_id":null,"html_url":"https://github.com/pg9182/ip2x","commit_stats":{"total_commits":58,"total_committers":1,"mean_commits":58.0,"dds":0.0,"last_synced_commit":"296a65ef35f6033d2618246f274b8557bbd6961e"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/pg9182/ip2x","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pg9182%2Fip2x","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pg9182%2Fip2x/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pg9182%2Fip2x/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pg9182%2Fip2x/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pg9182","download_url":"https://codeload.github.com/pg9182/ip2x/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pg9182%2Fip2x/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279013704,"owners_count":26085393,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["geolocation","go","ip","ip2location","library"],"created_at":"2024-11-06T10:32:50.193Z","updated_at":"2025-10-13T05:32:40.504Z","avatar_url":"https://github.com/pg9182.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ip2x\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/pg9182/ip2x.svg)](https://pkg.go.dev/github.com/pg9182/ip2x) [![test](https://github.com/pg9182/ip2x/actions/workflows/test.yml/badge.svg)](https://github.com/pg9182/ip2x/actions/workflows/test.yml) [![verify](https://github.com/pg9182/ip2x/actions/workflows/verify.yml/badge.svg)](https://github.com/pg9182/ip2x/actions/workflows/verify.yml)\n\nModule ip2x is an idiomatic, efficient, and robust library and command-line tool for querying [IP2Location](https://www.ip2location.com/) databases.\n\nCompared to [`github.com/ip2location/ip2location-go/v9`](https://github.com/ip2location/ip2location-go) and  [`github.com/ip2location/ip2proxy-go/v3`](https://github.com/ip2location/ip2proxy-go), this library:\n\n- Supports Go 1.18+.\n- Supports querying using Go 1.18's new [`net/netip.Addr`](https://pkg.go.dev/net/netip) type, which is much more efficient than parsing the IP from a string every time.\n- Uses native integer types instead of `big.Int`, which is also much more efficient.\n- Is about 11x faster than this library when querying a single field, and 2x faster for all fields, while making a fraction of the number of allocations (2 for init, 1 for each lookup, plus 1 for each typed field get, or 2 for an untyped one).\n- Has comprehensive built-in [documentation](https://pkg.go.dev/github.com/pg9182/ip2x), including automatically-generated information about which fields are available in different product types.\n- Supports querying information about the database itself, for example, whether it supports IPv6, and which fields are available.\n- Has a more fluent and flexible API (e.g., `record.Get(ip2x.Latitude)`, `record.GetString(ip2x.Latitude)`, `record.GetFloat(ip2x.Latitude)`)\n- Has built-in support for pretty-printing records as strings or JSON.\n- Supports both IP2Location databases in a single package with a unified API.\n- Uses code generation to simplify adding new products/types/fields/documentation while reducing the likelihood of bugs ([input](./dbdata.go), [docs](https://pkg.go.dev/github.com/pg9182/ip2x/internal/codegen)).\n- Is written in idiomatic Go: correct error handling (rather than stuffing error strings into the record struct), useful zero values (an empty record will work properly), proper type names, etc.\n- Has [tests](./test/correctness_test.go) to ensure the output is consistent with this library, that a range of IPv4 (and their possible IPv6-mappings) address work correctly, and other things. There are also [fuzz](./test/fuzz_test.go) tests to ensure IPs can't crash the library and are IPv4/v6-mapped correctly.\n- Has an automated [tool](./test/verifier/main.go) to compare the output of this library against the offical ones for every row of any database.\n\n## Benchmark\n\nThe code for the benchmark can be found in [benchmark_test.go](./test/benchmark_test.go).\n\n- Benchmarks are done using a balanced variety of IP addresses in both small and large subnets, as both IPv4 and IPv6 (native, v4-mapped, 6to4, and teredo). This ensures database indexing and IP parsing/normalization is tested fairly.\n- A test to ensure results from both libraries are the same exists to ensure correctness.\n- The entire DB is loaded into memory to ensure the disk cache does not affect results.\n\n```\ndb: IP2Location DB11 2022-10-29 [city,country_code,country_name,latitude,longitude,region,time_zone,zip_code] (IPv4+IPv6)\ngoos: linux\ngoarch: amd64\npkg: github.com/pg9182/ip2x/test\ncpu: AMD Ryzen 5 5600G with Radeon Graphics         \nBenchmarkIP2x_Init-12                       \t17850333\t        67.91 ns/op\t     128 B/op\t       2 allocs/op\nBenchmarkIP2x_LookupOnly-12                 \t18722506\t        61.36 ns/op\t      48 B/op\t       1 allocs/op\nBenchmarkIP2x_GetAll-12                     \t 1522696\t       812.2 ns/op\t    1688 B/op\t      14 allocs/op\nBenchmarkIP2x_GetOneString-12               \t 7839385\t       144.1 ns/op\t     304 B/op\t       2 allocs/op\nBenchmarkIP2x_GetOneFloat-12                \t14312419\t        84.16 ns/op\t      48 B/op\t       1 allocs/op\nBenchmarkIP2x_GetTwoString-12               \t 4243560\t       244.9 ns/op\t     560 B/op\t       3 allocs/op\nBenchmarkIP2x_GetTwoFloat-12                \t12198259\t       101.1 ns/op\t      48 B/op\t       1 allocs/op\nBenchmarkIP2x_GetNonexistent-12             \t14834245\t        79.85 ns/op\t      48 B/op\t       1 allocs/op\nBenchmarkIP2LocationV9_Init-12              \t  602967\t      2191 ns/op\t     400 B/op\t       7 allocs/op\nBenchmarkIP2LocationV9_LookupOnly-12        \t 1473849\t       782.6 ns/op\t     672 B/op\t      24 allocs/op\nBenchmarkIP2LocationV9_GetAll-12            \t  819900\t      1324 ns/op\t    2268 B/op\t      36 allocs/op\nBenchmarkIP2LocationV9_GetOneString-12      \t 1346534\t       889.2 ns/op\t     936 B/op\t      26 allocs/op\nBenchmarkIP2LocationV9_GetOneFloat-12       \t 1441219\t       795.0 ns/op\t     672 B/op\t      24 allocs/op\nBenchmarkIP2LocationV9_GetTwoString-12      \t  546868\t      1866 ns/op\t    1883 B/op\t      53 allocs/op\nBenchmarkIP2LocationV9_GetTwoFloat-12       \t  693019\t      1561 ns/op\t    1345 B/op\t      49 allocs/op\nBenchmarkIP2LocationV9_GetNonexistent-12    \t 1399872\t       795.5 ns/op\t     672 B/op\t      24 allocs/op\n```\n\n## CLI\n\n```\nip2x db_path [ip_addr...]\n  -compact\n        compact output\n  -json\n        use json output\n  -strict\n        fail immediately if a record is not found\n```\n\n```\n$ ip2x IP2LOCATION-LITE-DB11.IPV6.BIN 1.1.1.1\nIP2Location\u003cDB11\u003e{\n  city \"Los Angeles\"\n  country_code \"US\"\n  country_name \"United States of America\"\n  latitude 34.05286\n  longitude -118.24357\n  region \"California\"\n  time_zone \"-07:00\"\n  zip_code \"90001\"\n}\n```\n\n## Library\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/pg9182/ip2x\"\n)\n\nfunc main() {\n\tf, err := os.Open(\"IP2LOCATION-LITE-DB11.IPV6.BIN\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer f.Close()\n\n\tdb, err := ip2x.New(f)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(db)\n\tfmt.Println()\n\n\tr, err := db.LookupString(\"8.8.8.8\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// pretty-print\n\tfmt.Println(r.Format(true, true))\n\tfmt.Println()\n\n\t// get some fields the easy way\n\tfmt.Println(\"Test:\", r.Get(ip2x.CountryCode), r.Get(ip2x.Region))\n\n\t// get the latitude\n\t{\n\t\tfmt.Println()\n\t\tfmt.Printf(\"Get(Latitude): %#v\\n\", r.Get(ip2x.Latitude))\n\n\t\tlatstr, ok := r.GetString(ip2x.Latitude)\n\t\tfmt.Printf(\"GetString(Latitude): %#v, %#v\\n\", latstr, ok)\n\n\t\tlatflt, ok := r.GetFloat32(ip2x.Latitude)\n\t\tfmt.Printf(\"GetFloat32(Latitude): %#v, %#v\\n\", latflt, ok)\n\t}\n\n\t// get an unsupported field\n\t{\n\t\tfmt.Println()\n\t\tfmt.Printf(\"Get(ISP): %#v\\n\", r.Get(ip2x.ISP))\n\n\t\tispstr, ok := r.GetString(ip2x.ISP)\n\t\tfmt.Printf(\"GetString(ISP): %#v, %#v\\n\", ispstr, ok)\n\n\t\tispflt, ok := r.GetString(ip2x.ISP)\n\t\tfmt.Printf(\"GetString(ISP): %#v, %#v\\n\", ispflt, ok)\n\t}\n}\n```\n\n\u003cdetails\u003e\u003csummary\u003eOutput:\u003c/summary\u003e\n\n```\nIP2Location 2022-10-29 DB11 [city,country_code,country_name,latitude,longitude,region,time_zone,zip_code] (IPv4+IPv6)\n\nIP2Location\u003cDB11\u003e{\n  city \"Mountain View\"\n  country_code \"US\"\n  country_name \"United States of America\"\n  latitude 37.40599\n  longitude -122.078514\n  region \"California\"\n  time_zone \"-07:00\"\n  zip_code \"94043\"\n}\n\nTest: US California\n\nGet(Latitude): 37.40599\nGetString(Latitude): \"37.40599\", true\nGetFloat32(Latitude): 37.40599, true\n\nGet(ISP): \u003cnil\u003e\nGetString(ISP): \"\", false\nGetString(ISP): \"\", false\n```\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpg9182%2Fip2x","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpg9182%2Fip2x","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpg9182%2Fip2x/lists"}