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数据库 

  • 相关阅读:
    Windows Server 2003 SP2(32位) 中文版 下载地址 光盘整合方法
    用Recycle()方法对Java对象的重要性
    Lotus中千奇百怪的 $$
    Developing a simple application using steps "User Decision" and "Mail"(1) 沧海
    沟通中的情绪管理(演讲稿) 沧海
    人只有在压力之下,才可能成功,没做一件事,都必须成功,不许言败 沧海
    什么是IDOC,以及IDOC的步骤 沧海
    VS2008 Professional Edition CHS中的deffactory.dat读取错误 沧海
    Including custom text in the step "User Decision" 沧海
    SAP Upgrade Strategy 沧海
  • 原文地址:https://www.cnblogs.com/Death/p/2668590.html
Copyright © 2011-2022 走看看