【问题标题】:How to determine if an IP address belongs to a country如何判断一个IP地址是否属于一个国家
【发布时间】:2010-11-19 04:44:32
【问题描述】:

我将如何使用 c# 确定特定 IP 地址来自哪个国家/地区。我需要使用它来检查连接是否来自特定国家/地区。

【问题讨论】:

  • 我需要离线使用数据,因为它将用于统计数据。因此,我将使用 sql 选项

标签: c# .net geolocation


【解决方案1】:

您可以在项目中使用此 SQL 数据来确定:IP address geolocation SQL database。下载该数据并将其导入您的数据库以在本地运行检查。

或者您可以使用他们的免费 API,该 API 返回包含国家代码和国家名称的 XML。您将使用要检查的 IP 地址向以下 URL 发出请求,如本例所示:

http://ipinfodb.com/ip_query_country.php?ip=74.125.45.100

返回:

<Response>
<Ip>74.125.45.100</Ip>
<Status>OK</Status>
<CountryCode>US</CountryCode>
<CountryName>United States</CountryName>
</Response>

【讨论】:

  • 请注意,IP 分配偶尔会发生变化。所以记得偶尔更新你的数据库。 (您需要更新的频率取决于您在做什么;对于简单的统计数据,您可能会认为年度更新是可以的)。
  • 现在已经改变:您必须立即注册(免费)才能使用他们的 API。见这里:ipinfodb.com/ip_location_api.php
  • 它看起来已经改变了,该网站现在在主导航中有一个链接,最终导致以下下载:download.ip2location.com/lite 需要署名,但免费用于商业用途。此处的附加信息(即 IP 必须转换为 INT):lite.ip2location.com/database-ip-country
【解决方案2】:

只需一个简单的API 电话,例如https://ipapi.co/8.8.8.8/country/

美国

这是一个带有 working fiddle 的 C# 示例:

using System;
using System.Net;
using System.IO;
using System.Text;


public class Program
{
    public static void Main()
    {

      ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

      HttpWebRequest request   = (HttpWebRequest)WebRequest.Create("https://ipapi.co/8.8.8.8/country/");
      HttpWebResponse response = (HttpWebResponse)request.GetResponse();

      var reader = new System.IO.StreamReader(response.GetResponseStream(), ASCIIEncoding.ASCII);
      Console.WriteLine(reader.ReadToEnd());

    }
}

【讨论】:

    【解决方案3】:

    【讨论】:

      【解决方案4】:

      这是一个免费的IP Address to Country database

      【讨论】:

        【解决方案5】:

        如果您不想使用类似 hostip.info 的 API,那么我建议您订阅 maxmind 并在本地运行主机查找数据库。

        【讨论】:

          【解决方案6】:

          ip2cc - 通过 IP 地址查找国家和俄罗斯地区 Python 模块,使用脚本从最新的官方数据创建数据库。

          Python 实用程序从Regional Internet Registry 站点(arinripenccapniclacnicafrinic)加载(尽可能频繁地)最新信息,如shown in the source:

          url_template = 'ftp://ftp.ripe.net/pub/stats/%s/delegated-%s-latest'
          sources = {}
          for name in ('arin', 'ripencc', 'apnic', 'lacnic', 'afrinic'):
              sources[name] = url_template % (name, name)
          

          加载数据后,可以非常快速地离线回答查询。 可以轻松修改以直接回答原始问题,或者从命令行使用返回IP address 所属的国家/地区。

          【讨论】:

            【解决方案7】:

            离线数据库,可免费获取IP2Location LITE DB1

            创建表

            CREATE DATABASE ip2location
            GO
            
            USE ip2location
            GO
            
            CREATE TABLE [ip2location].[dbo].[ip2location_db1](
                [ip_from] float NOT NULL,
                [ip_to] float NOT NULL,
                [country_code] nvarchar(2) NOT NULL,
                [country_name] nvarchar(64) NOT NULL,
            ) ON [PRIMARY]
            GO
            
            CREATE INDEX [ip_from] ON [ip2location].[dbo].[ip2location_db1]([ip_from]) ON [PRIMARY]
            GO
            
            CREATE INDEX [ip_to] ON [ip2location].[dbo].[ip2location_db1]([ip_to]) ON [PRIMARY]
            GO
            

            导入数据

            BULK INSERT [ip2location].[dbo].[ip2location_db1]
                FROM 'C:\[path to your CSV file]\IP2LOCATION-LITE-DB1.CSV'
                WITH
                (
                    FORMATFILE = 'C:\[path to your DB1.FMT file]\DB1.FMT'
                )
            GO
            

            对于 FMT 文件

            10.0
            5
            1 SQLCHAR 0 1 "\"" 0 first_double_quote  Latin1_General_CI_AI
            2 SQLCHAR 0 20 "\",\"" 1 ip_from ""
            3 SQLCHAR 0 20 "\",\"" 2 ip_to ""
            4 SQLCHAR 0 2 "\",\"" 3 country_code Latin1_General_CI_AI
            5 SQLCHAR 0 64 "\"\r\n" 4 country_name Latin1_General_CI_AI
            

            FMT 代码的第一行表示 bcp 的版本。请根据您安装的 MS-SQL 更改版本。

            SQL Server 2016 12.0

            SQL Server 2014 12.0

            SQL Server 2012 11.0

            SQL Server 2008/2008 R2 10.0

            SQL Server 2005 9.0

            SQL Server 2000 8.0

            SQL Server 7.0 7.0

            SQL Server 6.5 6.5

            查询 MSSQL 的 C# 代码

            using System.Data.SqlClient;
            using System.Numerics;
            using System.Net;
            using System.Text;
            public class Form1 {
            
                private void Form1_Load(object sender, System.EventArgs e) {
                    string ip = "8.8.8.8";
                    this.IP2Location(ip);
                }
            
                private void IP2Location(string myip) {
                    IPAddress address = null;
                    if (IPAddress.TryParse(myip, address)) {
                        byte[] addrBytes = address.GetAddressBytes();
                        this.LittleEndian(addrBytes);
                        UInt32 ipno = 0;
                        ipno = BitConverter.ToUInt32(addrBytes, 0);
                        string sql = "SELECT TOP 1 * FROM ip2location_db1 WHERE ip_to >= \'" + ipno.ToString() + "\'";
                        object conn = new SqlConnection("Server=yourserver;Database=yourdatabase;User Id=youruserid;Password=yourpassword;");
                        object comm = new SqlCommand(sql, conn);
                        SqlDataReader reader;
                        comm.Connection.Open();
                        reader = comm.ExecuteReader(CommandBehavior.CloseConnection);
                        int x = 0;
                        object sb = new StringBuilder(250);
                        if (reader.HasRows) {
                            if (reader.Read()) {
                                for (x = 0; (x <= (reader.FieldCount() - 1)); x++) {
                                    sb.Append((reader.GetName(x) + (": " + (reader.GetValue(x) + "\r\n"))));
                                }
                            }
                        }
            
                        reader.Close();
                        MsgBox(sb.ToString());
                    }
            
                }
            
                private void LittleEndian(ref byte[] byteArr) {
                    if (BitConverter.IsLittleEndian) {
                        List<byte> byteList = new List<byte>(byteArr);
                        byteList.Reverse();
                        byteArr = byteList.ToArray();
                    }
            
                }
            }
            

            【讨论】:

              【解决方案8】:

              您可以使用的另一个服务是我自己的http://ipinfo.io,它返回位置、组织和其他信息:

              $ curl ipinfo.io/8.8.8.8
              {
                "ip": "8.8.8.8",
                "hostname": "google-public-dns-a.google.com",
                "loc": "37.385999999999996,-122.0838",
                "org": "AS15169 Google Inc.",
                "city": "Mountain View",
                "region": "California",
                "country": "US",
                "phone": 650
              }
              

              更多信息请参见http://ipinfo.io/developers

              【讨论】:

                【解决方案9】:

                以下是使用https://ipdata.co 的方法

                //Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
                //System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                
                //Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
                using System;
                using System.Net.Http;
                
                var baseAddress = new Uri("https://api.ipdata.co/78.8.53.5");
                
                using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
                {
                
                  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json");
                
                  using(var response = await httpClient.GetAsync("undefined"))
                  {
                
                        string responseData = await response.Content.ReadAsStringAsync();
                  }
                }
                

                通过卷发

                curl https://api.ipdata.co/78.8.53.5
                {
                    "ip": "78.8.53.5",
                    "city": "G\u0142og\u00f3w",
                    "region": "Lower Silesia",
                    "region_code": "DS",
                    "country_name": "Poland",
                    "country_code": "PL",
                    "continent_name": "Europe",
                    "continent_code": "EU",
                    "latitude": 51.6461,
                    "longitude": 16.1678,
                    "asn": "AS12741",
                    "organisation": "Netia SA",
                    "postal": "67-200",
                    "currency": "PLN",
                    "currency_symbol": "z\u0142",
                    "calling_code": "48",
                    "flag": "https://ipdata.co/flags/pl.png",
                    "emoji_flag": "\ud83c\uddf5\ud83c\uddf1",
                    "time_zone": "Europe/Warsaw",
                    "is_eu": true,
                    "suspicious_factors": {
                        "is_tor": false
                    }
                }⏎ 
                

                【讨论】:

                  【解决方案10】:

                  您可以使用IP Geolocation API 轻松做到这一点

                  它将返回国家、州、城市、时区和邮政编码。另外,请访问https://geo.ipify.org/docs 并免费试用。告诉我进展如何。

                  【讨论】:

                    【解决方案11】:

                    您可以使用https://astroip.co轻松查找任何IP地址

                    在 C# 中:

                    var url = "https://api.astroip.co/70.167.7.1/?api_key=1725e47c-1486-4369-aaff-463cc9764026";
                    
                    using (var httpClient = new HttpClient())
                    using(var resp = await httpClient.GetAsync(url))
                    {
                        string resp = await resp.Content.ReadAsStringAsync();
                     }
                    

                    在卷曲中:

                    卷曲https://api.astroip.co/70.167.7.1/?api_key=1725e47c-1486-4369-aaff-463cc9764026

                    {
                      "status_code": 200,
                      "geo": {
                        "is_metric": false,
                        "is_eu": false,
                        "longitude": -97.822,
                        "latitude": 37.751,
                        "country_geo_id": 6252001,
                        "zip_code": null,
                        "city": null,
                        "region_code": null,
                        "region_name": null,
                        "continent_code": "NA",
                        "continent_name": "North America",
                        "capital": "Washington",
                        "country_name": "United States",
                        "country_code": "US"
                      },
                      "asn": {
                        "route": "70.167.6.0/23",
                        "type": "isp",
                        "domain": "cox.net",
                        "organization": "ASN-CXA-ALL-CCI-22773-RDC",
                        "asn": "AS22773"
                      },
                      "currency": {
                        "native_name": "US Dollar",
                        "code": "USD",
                        "name": "US Dollar",
                        "symbol": "$"
                      },
                      "timezone": {
                        "is_dst": false,
                        "gmt_offset": -21600,
                        "date_time": "2020-11-23T15:15:56-06:00",
                        "microsoft_name": "Central Standard Time",
                        "iana_name": "America/Chicago"
                      },
                      "security": {
                        "is_crawler": false,
                        "is_proxy": false,
                        "is_tor": false,
                        "tor_insights": null,
                        "proxy_insights": null,
                        "crawler_insights": null
                      },
                      "crypto": null,
                      "user_agent": null,
                      "error": null,
                      "hostname": "wsip-70-167-7-1.sd.sd.cox.net",
                      "ip_type": "ipv4",
                      "ip": "70.167.7.1"
                    }
                    

                    【讨论】:

                      【解决方案12】:

                      这是一个将 IPAddress 转换为 UInt32 的扩展类。 从@vlam 的答案重构的代码

                      using System.Net;
                      
                      namespace Module.IP2Location.Core.Extensions;
                      
                      public static class IPAddressExtensions
                      {
                      
                          public static UInt32 ToUInt(this IPAddress address)
                          {
                      
                              byte[] addrBytes = address.GetAddressBytes();
                              if (BitConverter.IsLittleEndian)
                              {
                                  List<byte> byteList = new List<byte>(addrBytes);
                                  byteList.Reverse();
                                  addrBytes = byteList.ToArray();
                              }
                              UInt32 ipno = 0;
                              ipno = BitConverter.ToUInt32(addrBytes, 0);
                              return ipno;
                          }
                      
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 2013-11-07
                        • 1970-01-01
                        • 2014-12-23
                        • 1970-01-01
                        • 1970-01-01
                        • 2010-10-28
                        • 2011-03-26
                        • 2013-07-30
                        • 1970-01-01
                        相关资源
                        最近更新 更多