吐槽

前两天一个线上的IP地址库除了点幺蛾子,一查代码,发现用的库早就不更新了,遂决定换库,有几个方案:

纯真数据库是大码农的福音,免费,但是精度一般;IPIP有收费和免费版,免费版不定期更新,收费版精度高,有保障;GeoIP也是收费和免费版,免费版国内的城市精度一般,收费版比较精确,数据比较有特色,还同时提供了经纬度信息。

代码

纯真的数据在国家和省一级的数据还算精确,省下区域的精度不是特别的好,但胜在定期更新,完全免费,将下好的数据库转换为txt格式,并命名为ip.txt(有同学问我在哪现在,这个问题问的好,http://update.cz88.net/soft/setup.zip ,拿去不谢),数据到手,这里截取部分数据:

0.0.0.0         0.255.255.255   IANA 保留地址
1.0.0.0         1.0.0.0         美国 亚太互联网络信息中心(CloudFlare节点)
1.0.0.1         1.0.0.1         美国 APNIC&CloudFlare公共DNS服务器
1.0.0.2         1.0.0.255       美国 亚太互联网络信息中心(CloudFlare节点)
1.0.1.0         1.0.3.255       福建省 电信
1.0.4.0         1.0.7.255       澳大利亚 墨尔本Goldenit有限公司

很明显,第一列是起始IP、第二列是截止IP、第三列是地区、第四列是运营商信息,那么该如何查询呢,代码如下:

    public class IPCore
    {
        private static string IP_PATH ="ip.txt"; //数据文件地址
        private const string UnknowIP = "未知地址";
        private static Dictionary<int, List<IPInfo>> _ipCols = new Dictionary<int, List<IPInfo>>();

        /// <summary>
        /// 初始化数据。
        /// </summary>
        public static void Init()
        {
            try
            {
                if (_ipCols != null)
                    _ipCols.Clear();
                using (var sr = new StreamReader(IP_PATH, Encoding.Default))
                {
                    string curLine;
                    while (!string.IsNullOrEmpty(curLine = sr.ReadLine()))
                    {
                        string[] ipAddr = Regex.Split(curLine, "[\\s]+", RegexOptions.None);
                        if (ipAddr.Length < 3)
                            continue;
                        var startIP = ipAddr[0].Split('.');
                        var endIP = ipAddr[1].Split('.');
                        var ipAddress = UnknowIP;
                        if (ipAddr.Length == 4)
                        {
                            ipAddress = ipAddr[2];
                        }

                        IPInfo ipInfo = new IPInfo();
                        ipInfo.StartIP = Convert.ToUInt32(startIP[0]) * 1677216 + Convert.ToUInt32(startIP[1]) * 65536 + Convert.ToUInt32(startIP[2]) * 256 + Convert.ToUInt32(startIP[3]);
                        ipInfo.EndIP = Convert.ToUInt32(endIP[0]) * 1677216 + Convert.ToUInt32(endIP[1]) * 65536 + Convert.ToUInt32(endIP[2]) * 256 + Convert.ToUInt32(endIP[3]);
                        ipInfo.IpAddress = ipAddress;

                        int indexIP1 = Convert.ToInt32(startIP[0]);
                        int indexIP2 = Convert.ToInt32(endIP[0]);
                        for (int i = indexIP1; i <= indexIP2; i++)
                        {
                            if (!_ipCols.ContainsKey(i))
                            {
                                List<IPInfo> ipInfoList = new List<IPInfo>();
                                ipInfoList.Add(ipInfo);
                                _ipCols.Add(i, ipInfoList);
                            }
                            else
                            {
                                List<IPInfo> ipInfoList = _ipCols[i];
                                ipInfoList.Add(ipInfo);
                            }
                        }
                    }
                }

                //集合构建完成后对IP进行排序
                foreach (var key in _ipCols.Keys)
                {
                    _ipCols[key] = _ipCols[key].OrderBy(p => p.StartIP).ToList();
                }
            }
            catch (Exception ex)
            {
                //Log
            }
        }

        /// <summary>
        /// 获取IP地址。
        /// </summary>
        public static string GetIPAddress(string ip)
        {
            string[] addressIP = ip.Split('.');
            //计算ip对应long值
            long ipValue = Convert.ToUInt32(addressIP[0]) * 1677216 + Convert.ToUInt32(addressIP[1]) * 65536 + Convert.ToUInt32(addressIP[2]) * 256 + Convert.ToUInt32(addressIP[3]);
            int ipIndex = Convert.ToInt32(addressIP[0]);

            var ipInfos = _ipCols[ipIndex];

            int high = ipInfos.Count;
            for (int low = 0; low <= high;)
            {
                var point_index = (high + low) / 2;
                var ipInfo = ipInfos[point_index];
                if (ipValue < ipInfo.StartIP)
                {
                    high = point_index - 1;
                    continue;
                }
                else if (ipValue > ipInfo.EndIP)
                {
                    low = point_index + 1;
                    continue;
                }
                return ipInfo.IpAddress;
            }
            return UnknowIP;
        }

    }

    public class IPInfo
    {
        public long StartIP { get; set; }

        public long EndIP { get; set; }

        public string IpAddress { get; set; }
    }

IP地址库的更多相关文章

  1. 用淘宝ip地址库查ip

    这是一个通过调用淘宝ip地址库实现ip地址查询的功能类 using System; using System.Collections.Generic; using System.Linq; using ...

  2. Python之通过IP地址库获取IP地理信息

    利用第三方的IP地址库,各个公司可以根据自己的业务情况打造自己的IP地址采集分析系统.例如游戏公司可以采集玩家地区信息,进行有针对性的运营策略,还可能帮助分析玩家网络故障分布等等. #!/usr/bi ...

  3. Delphi使用JSON解析调用淘宝IP地址库REST API 示例

    淘宝IP地址库:http://ip.taobao.com,里面有REST API 说明. Delphi XE 调试通过,关键代码如下: var IdHTTP: TIdHTTP; RequestURL: ...

  4. 淘宝IP地址库采集器c#代码

    这篇文章主要介绍了淘宝IP地址库采集器c#代码,有需要的朋友可以参考一下. 最近做一个项目,功能类似于CNZZ站长统计功能,要求显示Ip所在的省份市区/提供商等信息.网上的Ip纯真数据库,下载下来一看 ...

  5. 淘宝IP地址库API接口(PHP)通过ip获取地址信息

    淘宝IP地址库网址:http://ip.taobao.com/ 提供的服务包括: 1. 根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家.省.市和运营商. 2. 用 ...

  6. 淘宝IP地址库采集

    作者:阿宝 更新:2016-08-31 来源:彩色世界(https://blog.hz601.org/2016/08/31/taobao-ip-sniffer/index.html) 简述 当初选择做 ...

  7. 【竞价网站绝技】根据访客ip,页面显示访客所属城市的html代码(借用YY IP地址库)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. thikphp5.0 ip地址库 解决卡顿问题 curl_init

    使用淘宝新浪的地址库非常的使用,但是调用有时候会出现很慢.会导致卡在当前网页. 要想不影响当前速度,因此要使用 curl_init功能. 项目案例:会员登陆日志 user_log 字段:id,user ...

  9. 淘宝IP地址库API地址

    淘宝IP地址库:http://ip.taobao.com/instructions.php   接口说明 1. 请求接口(GET): http://ip.taobao.com/service/getI ...

  10. XXX全球 IP 地址库

    XXX全球 IP 地址库 Bulgaria 93.123.23.1 93.123.23.2 93.123.23.3 93.123.23.4 93.123.23.5 93.123.23.6 93.123 ...

随机推荐

  1. querySelector

     this.el.nativeElement.querySelector import {Component, ElementRef, OnInit} from '@angular/core'; 

  2. Navicat 导出为 Excel 文件

    1:先选择一个表 再点击导出向导 2:看图   3:选择保存的路径  4:选择字段    5:最后执行吧 

  3. sublime text3 verilog代码编写高级操作篇

    2018.10.21 好久没写博客了,这段时间一直在学习一直在沉淀,然而发现学的越多会的更少,只能快马加鞭吧! 博主从大一暑假接触FPGA,到现在快一年半了,时间恍逝.刚开始入门也是用的quartus ...

  4. css3部分注意事项

    CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些? 1.选择器 id选择器( # myid) 类选择器(.myclassname) 标签选择器(div, h1, p ...

  5. MarkDown 语法及使用

    MarkDown #什么是Markdown - 定义 - markdown 是一款轻量级标记语言,功能没有HTML标记语言那么强大 ,Markdown专注书写! #试用人群: 程序员/等计算机爱好者 ...

  6. [ZJOJ] 5772【NOIP2008模拟】今天你AK了吗

    Description AK:All kill“你为什么没背书?”“没有为什么,我就是没背书.”“……我去年买了个表,G—U—N!”头铁王InFleaKing把背书的时间都拿去列排列了......n= ...

  7. Heaters (codeforces 1066B)

    贪心题 策略 在最左边设置一个array 0,每一次从右往左,如果有heater的话就寻找heater左边界是不是小于等于目前的上一个heater的右边界,如果没有一个这样的,那么就直接输出-1 代码 ...

  8. PHP排序算法之快速排序

    原理:找到当前数组中的任意一个元素(一般选择第一个元素),作为标准,新建两个空数组left.rignt,遍历整个数组元素,如果遍历到的元素比当前的元素小就放到数组left,比当前的元素大放到rignt ...

  9. 学习记录--让我打开另一种思路的SQL

    1.显示文章.提交人和最后回复时间 select a.title,a.username,b.adddate from table a, (select max(adddate) adddate fro ...

  10. navicate远程访问ubuntu上的mysql数据库

    安装mysql 首先检查系统中是否已经安装了MySQL,在终端里面输入: sudo netstat -tap | grep mysql 如上所示就是正确安装并启动,启动命令为 sudo /etc/in ...