吐槽

前两天一个线上的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. yagmail邮件模块

    昨天接到一个需求,就是要求用邮件发送一html文件.这里我想到了用yagmail #!/usr/bin/env python #-*- coding:utf-8 -*- import yagmail ...

  2. Silverlight之我见——DataGrid数据验证

    <UserControl x:Class="DataValidationSample.MainPage" xmlns="http://schemas.microso ...

  3. JavaScript初步学习----基本使用,简单事件,修改样式,数据类型

    JavaScript基本使用 JavaScript原名叫livescript,是一门动态类型,弱类型基于原型的脚本语言   用于页面特效,前后交替,后台开发(node)   JavaScript写在s ...

  4. 【codeforces 515D】Drazil and Tiles

    [题目链接]:http://codeforces.com/contest/515/problem/D [题意] 给你一个n*m的格子; 然后让你用1*2的长方形去填格子的空缺; 如果有填满的方案且方案 ...

  5. 手动扩栈#pragma comment(linker, "/STACK:1024000000,1024000000")

    #pragma comment(linker, "/STACK:1024000000,1024000000")

  6. 64位CentOS6.5下Eclipse用Java连接mysql

    1.到官网上下载jdbc驱动,我下载的是mysql-connector-java-5.0.8.tar.gz 2.解压下载到的文件 tar -zxvf mysql-connector-java-5.0. ...

  7. 【ACM】nyoj_132_最长回文子串_201308151713

    最长回文子串 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 输入一个字符串,求出其中最长的回文子串.子串的含义是:在原串连续出现的字符串片段.回文的含义是:正着看和 ...

  8. [bzoj1935][Shoi2007]Tree 园丁的烦恼 _树状数组

    Tree 园丁的烦恼 bzoj-1935 Shoi-2007 题目大意:给定平面上的$n$个点,$m$次查询矩形点个数. 注释:$1\le n,m\le 5\cdot 10^5$. 想法:静态二维数点 ...

  9. wait-notify模型面试题

    一道面试题: 启动两个线程, 一个输出 1,3,5,7-99, 另一个输出 2,4,6,8-100 最后 STDOUT 中按序输出 1,2,3,4,5-100 错误实现1: public class ...

  10. sqlserver 字符串函数

    转自:http://www.cnblogs.com/jiajiayuan/archive/2011/06/16/2082488.html 以下所有例子均Studnet表为例:  计算字符串长度len( ...