使用方法:
BDQQ.Data.QQWry qq=new BDQQ.Data.QQWry("d:\\QQWry.Dat");
BDQQ.Data.IPLocation ip=qq.SearchIPLocation("127.0.0.1");//这里添写IP地址
Console.WriteLine(ip.country);//国家
Console.WriteLine(ip.area);//地区
以下是基础类文件,和IP详细数据格式类 本文来自智动软件zdwork.cn
//根据LumaQQ改写而成.
using System;
using System.IO;
using System.Text;
namespace BDQQ.Data zdwork.cn 
...{ 智动软件

/**//**//**//// <summary> copyright 智动软件
/// QQWry 的摘要说明。
/// </summary>
public class QQWry 
...{ zdwork.cn
//第一种模式 
第一种模式#region 第一种模式 智动软件 
/**//**//**//// <summary> 本文来自智动软件zdwork.cn
/// 第一种模式
/// </summary>
#endregion
private const byte REDIRECT_MODE_1 = 0x01; 智动软件
//第二种模式 
第二种模式#region 第二种模式 
/**//**//**//// <summary>
/// 第二种模式
/// </summary>
#endregion
private const byte REDIRECT_MODE_2 = 0x02; copyright 智动软件
//每条记录长度 
每条记录长度#region 每条记录长度 本文来自智动软件zdwork.cn 
/**//**//**//// <summary> zdwork.cn
/// 每条记录长度
/// </summary>
#endregion
private const int IP_RECORD_LENGTH = 7; 内容来自zdwork.cn
//数据库文件 
数据库文件#region 数据库文件 
/**//**//**//// <summary> 智动软件
/// 文件对象
/// </summary>
#endregion
private FileStream ipFile;
private const string unCountry = "未知国家";
private const string unArea = "未知地区";
//索引开始位置 
索引开始位置#region 索引开始位置 zdwork.cn 
/**//**//**//// <summary> 本文来自智动软件zdwork.cn
/// 索引开始位置
/// </summary>
#endregion
private long ipBegin;
//索引结束位置 copyright 智动软件

索引结束位置#region 索引结束位置 www.zdwork.cn

/**//**//**//// <summary> 本文来自智动软件zdwork.cn
/// 索引结束位置
/// </summary>
#endregion
private long ipEnd;
//IP地址对象 本文来自智动软件zdwork.cn 
IP地址对象#region IP地址对象 智动软件

/**//**//**//// <summary> zdwork.cn
/// IP对象
/// </summary>
#endregion
private IPLocation loc;
//存储文本内容 本文来自智动软件zdwork.cn

存储文本内容#region 存储文本内容 
/**//**//**//// <summary>
/// 存储文本内容
/// </summary>
#endregion
private byte[] buf;
//存储3字节 
存储3字节#region 存储3字节 本文来自智动软件zdwork.cn 
/**//**//**//// <summary> www.zdwork.cn
/// 存储3字节
/// </summary>
#endregion
private byte[] b3;
//存储4字节 copyright 智动软件 
存储4字节#region 存储4字节 zdwork.cn 
/**//**//**//// <summary>
/// 存储4字节IP地址
/// </summary>
#endregion
private byte[] b4;
//构造函数 智动软件

构造函数#region 构造函数 内容来自zdwork.cn 
/**//**//**//// <summary> 内容来自zdwork.cn
/// 构造函数
/// </summary>
/// <param name="ipfile">IP数据库文件绝对路径</param>
#endregion www.zdwork.cn
public QQWry( string ipfile ) 
...{ copyright 智动软件
buf = new byte[100];
b3 = new byte[3];
b4 = new byte[4];
try 
...{ copyright 智动软件
ipFile = new FileStream( ipfile,FileMode.Open );
}
catch( Exception ex ) 
...{
throw new Exception( ex.Message );
}
ipBegin = readLong4(0);
ipEnd = readLong4(4);
loc = new IPLocation(); 智动软件
} 
//根据IP地址搜索 
根据IP地址搜索#region 根据IP地址搜索 内容来自zdwork.cn 
/**//**//**//// <summary> www.zdwork.cn
/// 搜索IP地址搜索
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
#endregion 智动软件
public IPLocation SearchIPLocation( string ip ) 
...{ 智动软件
//将字符IP转换为字节
string[] ipSp = ip.Split('.');
if( ipSp.Length != 4 ) 
...{ 本文来自智动软件zdwork.cn
throw new ArgumentOutOfRangeException( "不是合法的IP地址!" );
}
byte[] IP = new byte[4];
for( int i = 0; i < IP.Length ; i++ ) 智动软件 
...{ 内容来自zdwork.cn
IP[i] = (byte)(Int32.Parse( ipSp[i] ) & 0xFF) ;
}
IPLocation local = null;
long offset = locateIP( IP );
if( offset != -1 ) copyright 智动软件 
...{
local = getIPLocation( offset );
}
if( local == null ) 
...{ copyright 智动软件
local = new IPLocation();
local.area = unArea;
local.country = unCountry;
}
return local;
}
智动软件
//取得具体信息 
取得具体信息#region 取得具体信息 
/**//**//**//// <summary>
/// 取得具体信息
/// </summary>
/// <param name="offset"></param>
/// <returns></returns>
#endregion
private IPLocation getIPLocation( long offset ) 
...{ copyright 智动软件
ipFile.Position = offset + 4;
//读取第一个字节判断是否是标志字节
byte one = (byte)ipFile.ReadByte();
if( one == REDIRECT_MODE_1 ) zdwork.cn 
...{ 内容来自zdwork.cn
//第一种模式
//读取国家偏移
long countryOffset = readLong3();
//转至偏移处
ipFile.Position = countryOffset; copyright 智动软件
//再次检查标志字节
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;
} 
//取得地区信息 
取得地区信息#region 取得地区信息 copyright 智动软件

/**//**//**//// <summary> www.zdwork.cn
/// 读取地区名称
/// </summary>
/// <param name="offset"></param>
/// <returns></returns>
#endregion copyright 智动软件
private string readArea( long offset ) 
...{
ipFile.Position = offset;
byte one = (byte)ipFile.ReadByte();
if( one == REDIRECT_MODE_1 || one == REDIRECT_MODE_2 ) 
...{ zdwork.cn
long areaOffset = readLong3( offset + 1 );
if( areaOffset == 0 )
return unArea;
else www.zdwork.cn

...{ zdwork.cn
return readString( areaOffset );
}
}
else 
...{ 本文来自智动软件zdwork.cn
return readString( offset );
}
} 
//读取字符串 
读取字符串#region 读取字符串 
/**//**//**//// <summary> 智动软件
/// 读取字符串
/// </summary>
/// <param name="offset"></param>
/// <returns></returns>
#endregion 智动软件
private string readString( long offset ) 
...{ www.zdwork.cn
ipFile.Position = offset;
int i = 0;
for(i = 0, buf[i]=(byte)ipFile.ReadByte();buf[i] != (byte)(0);buf[++i]=(byte)ipFile.ReadByte()); copyright 智动软件
if( i > 0 )
return Encoding.Default.GetString( buf,0,i );
else
return "";
} 本文来自智动软件zdwork.cn

//查找IP地址所在的绝对偏移量 
查找IP地址所在的绝对偏移量#region 查找IP地址所在的绝对偏移量 本文来自智动软件zdwork.cn 
/**//**//**//// <summary>
/// 查找IP地址所在的绝对偏移量
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
#endregion 内容来自zdwork.cn
private long locateIP( byte[] ip ) 
...{ www.zdwork.cn
long m = 0;
int r;
//比较第一个IP项
readIP( ipBegin, b4 );
r = compareIP( ip,b4);
if( r == 0 ) 内容来自zdwork.cn
return ipBegin;
else if( r < 0 )
return -1;
//开始二分搜索
for( long i = ipBegin,j=ipEnd; i<j; ) zdwork.cn

...{ 智动软件
m = this.getMiddleOffset( i,j );
readIP( m,b4 );
r = compareIP( ip,b4 );
if( r > 0 )
i = m;
else if( r < 0 ) 
...{
if( m == j ) 
...{ 本文来自智动软件zdwork.cn
j -= IP_RECORD_LENGTH;
m = j;
}
else 
...{ 内容来自zdwork.cn
j = m;
}
}
else
return readLong3( m+4 );
}
m = readLong3( m+4 ); 本文来自智动软件zdwork.cn
readIP( m,b4 );
r = compareIP( ip,b4 );
if( r <= 0 )
return m;
else
return -1; zdwork.cn
} 
//读出4字节的IP地址 
读出4字节的IP地址#region 读出4字节的IP地址 
/**//**//**//// <summary>
/// 从当前位置读取四字节,此四字节是IP地址
/// </summary>
/// <param name="offset"></param>
/// <param name="ip"></param>
#endregion 智动软件
private void readIP( long offset, byte[] ip ) 
...{ 本文来自智动软件zdwork.cn
ipFile.Position = offset;
ipFile.Read( ip,0,ip.Length );
byte tmp = ip[0];
ip[0] = ip[3];
ip[3] = tmp; www.zdwork.cn
tmp = ip[1];
ip[1] = ip[2];
ip[2] = tmp;
} 
//比较IP地址是否相同 智动软件 
比较IP地址是否相同#region 比较IP地址是否相同 本文来自智动软件zdwork.cn 
/**//**//**//// <summary> www.zdwork.cn
/// 比较IP地址是否相同
/// </summary>
/// <param name="ip"></param>
/// <param name="beginIP"></param>
/// <returns>0:相等,1:ip大于beginIP,-1:小于</returns> www.zdwork.cn
#endregion
private int compareIP( byte[] ip, byte[] beginIP ) 
...{ 内容来自zdwork.cn
for( int i = 0; i < 4; i++ ) 
...{ 本文来自智动软件zdwork.cn
int r = compareByte( ip[i],beginIP[i] );
if( r != 0 )
return r;
}
return 0; 本文来自智动软件zdwork.cn
} 
//比较两个字节是否相等 
比较两个字节是否相等#region 比较两个字节是否相等 本文来自智动软件zdwork.cn

/**//**//**//// <summary> 智动软件
/// 比较两个字节是否相等
/// </summary>
/// <param name="bsrc"></param>
/// <param name="bdst"></param>
/// <returns></returns>
#endregion
private int compareByte( byte bsrc, byte bdst ) 
...{ 本文来自智动软件zdwork.cn
if( ( bsrc&0xFF ) > ( bdst&0xFF ) )
return 1;
else if( (bsrc ^ bdst) == 0 ) zdwork.cn
return 0;
else
return -1;
} 
//根据当前位置读取4字节 www.zdwork.cn

根据当前位置读取4字节#region 根据当前位置读取4字节 智动软件 
/**//**//**//// <summary> www.zdwork.cn
/// 从当前位置读取4字节,转换为长整型
/// </summary>
/// <param name="offset"></param>
/// <returns></returns>
#endregion copyright 智动软件
private long readLong4( long offset ) 
...{ www.zdwork.cn
long ret = 0;
ipFile.Position = offset;
ret |= ( ipFile.ReadByte() & 0xFF );
ret |= ( ( ipFile.ReadByte() << 8 ) & 0xFF00 ); www.zdwork.cn
ret |= ( ( ipFile.ReadByte() << 16 ) & 0xFF0000 );
ret |= ( ( ipFile.ReadByte() << 24 ) & 0xFF000000 );
return ret; www.zdwork.cn
} 
//根据当前位置,读取3字节 
根据当前位置,读取3字节#region 根据当前位置,读取3字节 
/**//**//**//// <summary> 本文来自智动软件zdwork.cn
/// 根据当前位置,读取3字节
/// </summary>
/// <param name="offset"></param>
/// <returns></returns>
#endregion zdwork.cn
private long readLong3( long offset ) 
...{ 内容来自zdwork.cn
long ret = 0;
ipFile.Position = offset;
ret |= ( ipFile.ReadByte() & 0xFF );
ret |= ( (ipFile.ReadByte() << 8 ) & 0xFF00 );
ret |= ( (ipFile.ReadByte() << 16 ) & 0xFF0000 );
return ret;
} 
//从当前位置读取3字节 www.zdwork.cn 
从当前位置读取3字节#region 从当前位置读取3字节 智动软件 
/**//**//**//// <summary>
/// 从当前位置读取3字节
/// </summary>
/// <returns></returns>
#endregion
private long readLong3() 本文来自智动软件zdwork.cn

...{ zdwork.cn
long ret = 0;
ret |= ( ipFile.ReadByte() & 0xFF );
ret |= ( (ipFile.ReadByte() << 8 ) & 0xFF00 ); 本文来自智动软件zdwork.cn
ret |= ( (ipFile.ReadByte() << 16 ) & 0xFF0000 );
return ret;
} 
//取得begin和end之间的偏移量 内容来自zdwork.cn

取得begin和end之间的偏移量#region 取得begin和end之间的偏移量 copyright 智动软件

/**//**//**//// <summary> 内容来自zdwork.cn
/// 取得begin和end中间的偏移
/// </summary>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <returns></returns> 内容来自zdwork.cn
#endregion
private long getMiddleOffset( long begin, long end ) 
...{ zdwork.cn
long records = ( end - begin ) / IP_RECORD_LENGTH;
records >>= 1;
if( records == 0 )
records = 1; 本文来自智动软件zdwork.cn
return begin + records * IP_RECORD_LENGTH;
}
} //class QQWry
public class IPLocation 
...{ 内容来自zdwork.cn
public String country;
public String area;
public IPLocation() 
...{ 内容来自zdwork.cn
country = area = "";
}
public IPLocation getCopy() 
...{
IPLocation ret = new IPLocation();
ret.country = country;
ret.area = area;
return ret;
}
}
} 
