吐槽

前两天一个线上的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. MongoDB主库和从库的数据大小不一致原因判断

    1. 环境(MongoDB的版本是3.2.16) [root@xxx-mongodb-primary ~]# cat /etc/redhat-release CentOS Linux release ...

  2. win10如何进入安全模式的几种方法

    首先,说一下安全模式的作用: 安全模式, 用途有很多,常见的作用有以下几点 1. 电脑可能由于安装了某些驱动或者软件,不兼容导致电脑启动不了,可以进入安全模式卸载 2. 电脑中病毒之后,可以进入安全模 ...

  3. 【tips】ORM - SQLAlchemy操作MySQL数据库

    优先(官方文档SQLAlchemy-version1.2): sqlalchemy | 作者:斯芬克斯 推荐一(长篇幅version1.2.0b3):python约会之ORM-sqlalchemy | ...

  4. vue监听数组中某个属性,计算其他属性问题

    今天在项目开发中遇到一个根据数组中某个属性变化同时更新另一个属性变化的问题,刚开始代码如下 this.weekList1=r.data.roomProducts; this.weekList1.map ...

  5. mybatis源码阅读-执行器Executor(四)

    说明 前面二看到了 sqlSession最终是找到MapperStatement然后委托给Executer执行的 Executer到底做了什么 接口定义 public interface Execut ...

  6. 联赛前集训日记Day1

    考试 炸的凄惨 T1 显然要高精搞一下,然而我的$DFS$竟然比我的$O(n^{2})$递推快 T2 欧拉路径的题,很不可做的样子,就没敢费时间打 T3 $DFS$枚举可过,然而我太蠢 GG 刷题 改 ...

  7. poj 2553强连通+缩点

    /*先吐槽下,刚开始没看懂题,以为只能是一个连通图0T0 题意:给你一个有向图,求G图中从v可达的所有点w,也都可以达到v,这样的v称为sink.求这样的v. 解;求强连通+缩点.求所有出度为0的点即 ...

  8. 络谷 P2865 [USACO06NOV]路障Roadblocks

    P2865 [USACO06NOV]路障Roadblocks 题目描述 Bessie has moved to a small farm and sometimes enjoys returning ...

  9. LA 4794 状态DP+子集枚举

    状态压缩DP,把切割出的面积做状态压缩,统计出某状态下面积和. 设f(x,y,S)为在状态为S下在矩形x,y是否存在可能划分出S包含的面积.若S0是S的子集,对矩形x,y横切中竖切,对竖切若f(x,k ...

  10. java package 命名空间

    原文: http://www.studytonight.com/java/package-in-java.php 创建一个简单的maven 项目的命令是: mvn  archetype:generat ...