zoukankan      html  css  js  c++  java
  • 纯真IP数据库

    相关类(转):
    View Code 
        /// <summary>
        
    ///QQWry 的摘要说明
        //纯真版QQ IP数据库下载:http://www.cz88.net/fox/
        /// </summary>
        public class QQWry
        {
            //Singleton
            static QQWry instance;
            public static QQWry GetInstance(string dataPath)
            {
                if (instance == null)
                    instance = new QQWry(dataPath);

                return instance;
            }


            //第一种模式
            private const byte REDIRECT_MODE_1 = 0x01;

            //第二种模式
            private const byte REDIRECT_MODE_2 = 0x02;

            //每条记录长度
            private const int IP_RECORD_LENGTH = 7;

            //数据库文件
            private FileStream ipFile;
            private string ipFile2;

            private const string unCountry = "未知国家";
            private const string unArea = "未知地区";

            //索引开始位置
            private long ipBegin;

            //索引结束位置
            private long ipEnd;

            //IP地址对象
            private QQIPLocation loc;

            //存储文本内容
            private byte[] buf;

            //存储3字节
            private byte[] b3;

            //存储4字节
            private byte[] b4;

            /// <summary>
            
    /// 构造函数
            
    /// </summary>
            
    /// <param name="ipfile">IP数据库文件绝对路径</param>
            
    /// <returns></returns>
            public QQWry(string ipfile)
            {

                buf = new byte[100];
                b3 = new byte[3];
                b4 = new byte[4];
                ipFile2 = ipfile;

            }

            /// <summary>
            
    /// 搜索IP地址搜索
            
    /// </summary>
            
    /// <param name="ip"></param>
            
    /// <returns></returns>
            public QQIPLocation SearchIPLocation(string ip)
            {
                try
                {
                    ipFile = new FileStream(ipFile2, FileMode.Open);

                    ipBegin = readLong4(0);
                    ipEnd = readLong4(4);
                    loc = new QQIPLocation();


                    //将字符IP转换为字节
                    string[] ipSp = ip.Split('.');
                    if (ipSp.Length != 4)
                    {
                        throw new ArgumentOutOfRangeException("不是合法的IP地址!");
                    }
                    byte[] IP = new byte[4];
                    for (int i = 0; i < IP.Length; i++)
                    {
                        IP[i] = (byte)(Int32.Parse(ipSp[i]) & 0xFF);
                    }

                    QQIPLocation local = null;
                    long offset = locateIP(IP);

                    if (offset != -1)
                    {
                        local = getIPLocation(offset);
                    }

                    if (local == null)
                    {
                        local = new QQIPLocation();
                        local.area = unArea;
                        local.country = unCountry;
                    }

                    ipFile.Dispose();

                    return local;
                }
                catch
                {
                    return new QQIPLocation();
                }
                finally
                {
                    ipFile.Dispose();
                }
            }

            /// <summary>
            
    /// 取得具体信息
            
    /// </summary>
            
    /// <param name="offset"></param>
            
    /// <returns></returns>
            private QQIPLocation getIPLocation(long offset)
            {
                ipFile.Position = offset + 4;
                //读取第一个字节判断是否是标志字节
                byte one = (byte)ipFile.ReadByte();
                if (one == REDIRECT_MODE_1)
                {
                    //第一种模式
                    
    //读取国家偏移
                    long countryOffset = readLong3();
                    //转至偏移处
                    ipFile.Position = countryOffset;
                    //再次检查标志字节
                    byte b = (byte)ipFile.ReadByte();
                    if (b == REDIRECT_MODE_2)
                    {
                        loc.country = readString(readLong3());
                        ipFile.Position = countryOffset + 4;
                    }
                    else
                        loc.country = readString(countryOffset);

                    //读取地区标志
                    loc.area = readArea(ipFile.Position);

                }
                else if (one == REDIRECT_MODE_2)
                {
                    //第二种模式
                    loc.country = readString(readLong3());
                    loc.area = readArea(offset + 8);
                }
                else
                {
                    //普通模式
                    loc.country = readString(--ipFile.Position);
                    loc.area = readString(ipFile.Position);
                }
                return loc;
            }

            /// <summary>
            
    /// 读取地区名称
            
    /// </summary>
            
    /// <param name="offset"></param>
            
    /// <returns></returns>
            private string readArea(long offset)
            {
                ipFile.Position = offset;
                byte one = (byte)ipFile.ReadByte();
                if (one == REDIRECT_MODE_1 || one == REDIRECT_MODE_2)
                {
                    long areaOffset = readLong3(offset + 1);
                    if (areaOffset == 0)
                        return unArea;
                    else
                    {
                        return readString(areaOffset);
                    }
                }
                else
                {
                    return readString(offset);
                }
            }

            /// <summary>
            
    /// 读取字符串
            
    /// </summary>
            
    /// <param name="offset"></param>
            
    /// <returns></returns>
            private string readString(long offset)
            {
                ipFile.Position = offset;
                int i = 0;
                for (i = 0, buf[i] = (byte)ipFile.ReadByte(); buf[i] != (byte)(0); buf[++i] = (byte)ipFile.ReadByte()) ;

                if (i > 0)
                    return Encoding.Default.GetString(buf, 0, i);
                else
                    return "";
            }

            /// <summary>
            
    /// 查找IP地址所在的绝对偏移量
            
    /// </summary>
            
    /// <param name="ip"></param>
            
    /// <returns></returns>
            private long locateIP(byte[] ip)
            {
                long m = 0;
                int r;

                //比较第一个IP项
                readIP(ipBegin, b4);
                r = compareIP(ip, b4);
                if (r == 0)
                    return ipBegin;
                else if (r < 0)
                    return -1;
                //开始二分搜索
                for (long i = ipBegin, j = ipEnd; i < j; )
                {
                    m = this.getMiddleOffset(i, j);
                    readIP(m, b4);
                    r = compareIP(ip, b4);
                    if (r > 0)
                        i = m;
                    else if (r < 0)
                    {
                        if (m == j)
                        {
                            j -= IP_RECORD_LENGTH;
                            m = j;
                        }
                        else
                        {
                            j = m;
                        }
                    }
                    else
                        return readLong3(m + 4);
                }
                m = readLong3(m + 4);
                readIP(m, b4);
                r = compareIP(ip, b4);
                if (r <= 0)
                    return m;
                else
                    return -1;
            }

            /// <summary>
            
    /// 从当前位置读取四字节,此四字节是IP地址
            
    /// </summary>
            
    /// <param name="offset"></param>
            
    /// <param name="ip"></param>
            private void readIP(long offset, byte[] ip)
            {
                ipFile.Position = offset;
                ipFile.Read(ip, 0, ip.Length);
                byte tmp = ip[0];
                ip[0] = ip[3];
                ip[3] = tmp;
                tmp = ip[1];
                ip[1] = ip[2];
                ip[2] = tmp;
            }

            /// <summary>
            
    /// 比较IP地址是否相同
            
    /// </summary>
            
    /// <param name="ip"></param>
            
    /// <param name="beginIP"></param>
            
    /// <returns>0:相等,1:ip大于beginIP,-1:小于</returns>
            private int compareIP(byte[] ip, byte[] beginIP)
            {
                for (int i = 0; i < 4; i++)
                {
                    int r = compareByte(ip[i], beginIP[i]);
                    if (r != 0)
                        return r;
                }
                return 0;
            }

            /// <summary>
            
    /// 比较两个字节是否相等
            
    /// </summary>
            
    /// <param name="bsrc"></param>
            
    /// <param name="bdst"></param>
            
    /// <returns></returns>
            private int compareByte(byte bsrc, byte bdst)
            {
                if ((bsrc & 0xFF) > (bdst & 0xFFL))
                    return 1;
                else if ((bsrc ^ bdst) == 0)
                    return 0;
                else
                    return -1;
            }

            /// <summary>
            
    /// 从当前位置读取4字节,转换为长整型
            
    /// </summary>
            
    /// <param name="offset"></param>
            
    /// <returns></returns>
            private long readLong4(long offset)
            {
                long ret = 0;
                ipFile.Position = offset;
                ret |= (ipFile.ReadByte() & 0xFFL);
                ret |= ((ipFile.ReadByte() << 8) & 0xFF00L);
                ret |= ((ipFile.ReadByte() << 16) & 0xFF0000L);
                ret |= ((ipFile.ReadByte() << 24) & 0xFF000000L);
                return ret;
            }

            /// <summary>
            
    /// 根据当前位置,读取3字节
            
    /// </summary>
            
    /// <param name="offset"></param>
            
    /// <returns></returns>
            private long readLong3(long offset)
            {
                long ret = 0;
                ipFile.Position = offset;
                ret |= (ipFile.ReadByte() & 0xFFL);
                ret |= ((ipFile.ReadByte() << 8) & 0xFF00L);
                ret |= ((ipFile.ReadByte() << 16) & 0xFF0000L);
                return ret;
            }

            /// <summary>
            
    /// 从当前位置读取3字节
            
    /// </summary>
            
    /// <returns></returns>
            private long readLong3()
            {
                long ret = 0;
                ret |= (ipFile.ReadByte() & 0xFFL);
                ret |= ((ipFile.ReadByte() << 8) & 0xFF00L);
                ret |= ((ipFile.ReadByte() << 16) & 0xFF0000L);
                return ret;
            }

            /// <summary>
            
    /// 取得begin和end中间的偏移
            
    /// </summary>
            
    /// <param name="begin"></param>
            
    /// <param name="end"></param>
            
    /// <returns></returns>
            private long getMiddleOffset(long begin, long end)
            {
                long records = (end - begin) / IP_RECORD_LENGTH;
                records >>= 1;
                if (records == 0)
                    records = 1;
                return begin + records * IP_RECORD_LENGTH;
            } 
        }

        public class QQIPLocation
        {
            public String country;
            public String area;

            public String Prvoince
            {
                get
                {
                    if (string.IsNullOrEmpty(country))
                        return "";

                    int pos = country.IndexOf("");
                    if (pos == -1)
                        return "";

                    return country.Substring(0, country.Length - pos - 2);
                }
            }

            public String City
            {
                get
                {
                    if (string.IsNullOrEmpty(country))
                        return "";

                    int start = country.IndexOf("");
                    int pos = country.IndexOf("");
                    if (pos == -1)
                        return "";

                    return country.Substring(start + 1, pos - start - 1);
                }
            }

            public QQIPLocation()
            {
                country = area = "";
            }

            public QQIPLocation getCopy()
            {
                QQIPLocation ret = new QQIPLocation();
                ret.country = country;
                ret.area = area;
                return ret;
            }

    调用方法:
    var wry = QQWry.GetInstance(page.Server.MapPath("~/QQWry.Dat"));
    var location = wry.SearchIPLocation("60.191.244.5");

    附件:

    纯真IP数据库 

  • 相关阅读:
    杨老师课堂_VBA学习教程之一键合并所有文件
    无题
    杨老师课堂_VBA学习教程之VBA中使用函数
    杨老师课堂_Java核心技术下之控制台模拟文件管理器案例
    杨老师课堂之JavaScript定时器_农夫山泉限时秒杀案例
    交换机级联,堆叠,集群技术介绍
    IP划分
    光纤
    交换机
    URL中“#” “?” &“”号的作用
  • 原文地址:https://www.cnblogs.com/Death/p/2668590.html
Copyright © 2011-2022 走看看