吐槽

前两天一个线上的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. IE浏览器new Date()带参返回NaN解决方法

    var start = '2016-01-01 12:12:12'; var date = new Date(start); 得到的时间为NaN: 解决方法: 1.自定义方法 自定义一个NewDate ...

  2. 网络编程_socketserver

    一.socketserver 网络编程 1.socketserver支持多用户并发处理:2.socketserver是对socket的再封装;处理步骤:1.创建一个socketserver类2.继承B ...

  3. php第十八节课

    PDO 对不同的数据库连接使用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...

  4. CF36E Two Paths (欧拉回路+构造)

    题面传送门 题目大意:给你一张可能有重边的不保证联通的无向图,现在要在这个图上找出两条路径,恰好能覆盖所有边一次,根据边的编号输出方案,无解输出-1 一道很不错的欧拉路径变形题 首先要知道关于欧拉路径 ...

  5. The meaning of the number displayed on the man page in Linux

    0 Header files 0p Header files (POSIX) 1 Executable programs or shell commands 1p Executable program ...

  6. Python中的@property装饰器

    要了解@property的用途,首先要了解如何创建一个属性. 一般而言,属性都通过__init__方法创建,比如: class Student(object): def __init__(self,n ...

  7. BZOJ 1614 USACO 07Jan. 洛谷1948 电话线

    二分+特殊姿势的check:二分最小代价P,把边权小于等于P的边设为0,其他的设为1,跑一遍最短路,判断dis[n]是否大于K #include<cstdio> #include<a ...

  8. Django——9 博客小案例的实现

    Django  博客小案例的实现 主要实现博客的增删改查功能 主页index.html  -->  展示添加博客和博客列表的文字,实现页面跳转 添加页add.html  --> 输入文章标 ...

  9. ACDream - Sum

    先上题目: Sum Time Limit: 6000/3000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitSta ...

  10. sencha touch 2中判断游览器是否包含webkit的方法

    <script type="text/javascript"> if (!Ext.browser.is.WebKit) { alert("The curren ...