吐槽

前两天一个线上的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. .net core里用ZXing生成二维码

    先获取Nuget包 static void Main(string[] args) { string content = "二维码信息"; BitMatrix byteMatrix ...

  2. Android 双屏异显

    android双屏是克隆模式,如果要在第二屏幕显示不同内容,需要自定义一个Presentation类 1.先设置权限 (刚开始折腾很久没有效果,后来发现是没设置权限) <!-- 显示系统窗口权限 ...

  3. CAD对象的夹点被编辑完成后调用事件(com接口VB语言)

    主要用到函数说明: _DMxDrawXEvents::ObjectGripEdit 对象的夹点被编辑完成后,会调用该事件,详细说明如下: 参数 说明 LONGLONG lId 对象的id LONG i ...

  4. 【LeetCode】1、Two Sum

    题目等级:Easy 题目描述:   Given an array of integers, return indices of the two numbers such that they add u ...

  5. openoffice启动服务并将office文件转换为pdf文件

    1.首先下载最新版的openoffice工具,安装完成之后安装服务,, win+r打开命令提示符 输入cmd,cd C:\Program Files (x86)\OpenOffice 4\progra ...

  6. python爬虫12 | 爸爸,他使坏,用动态的 Json 数据,我要怎么搞?

    在前面我们玩了好多静态的 HTML 想必你应该知道怎么去爬这些数据了 但还有一些常见的动态数据 比如 商品的评论数据 实时的直播弹幕 岛国动作片的评分 等等 这些数据是会经常发生改变的 很多网站就会用 ...

  7. SecureCRT的设置和美化

    一  . SecureCRT 7.1  的 安装     http://liufei888.blog.51cto.com/2625545/1306231 1.下载注册机SecureCRT.v.6.7. ...

  8. 知新之--12-factors

    作为总的原则,在程序设计上很有高度... 参考URL:http://12factor.net/zh_cn/ ========================================== 12- ...

  9. [bzoj3378][Usaco2004 Open]MooFest 狂欢节_树状数组

    MooFest 狂欢节 bzoj-3378 Usaco-2004 Open 题目大意:给定一个n个数的a序列,每两个数之间有一个距离,两个点之间的权值为$max(a[i],a[j])*dis(i,j) ...

  10. [bzoj1941][Sdoi2010]Hide and Seek_KD-Tree

    Hide and Seek bzoj-1941 Sdoi-2010 题目大意:给出平面上n个点,选出一个点,使得距离这个点的最远点曼哈顿距离减去距离这个点的最近非己点的曼哈顿距离最小.输出最小曼哈顿距 ...