纯真IP数据库

相关类(转):
ExpandedBlockStart.gif 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数据库 

转载于:https://www.cnblogs.com/Death/archive/2012/09/03/2668590.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值