当前位置: 编程技术>.net/c#/asp.net
C#读取QQ纯真IP数据库QQWry.Dat的代码
来源: 互联网 发布时间:2014-10-13
本文导语: 纯真版QQ IP数据库 代码如下: using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Web; using System.Configuration; namespace BLL { public class IPLocationSearch { private static readonly QQWry qq = new QQWry(ConfigurationManager.AppSettings["ip...
纯真版QQ IP数据库
代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web;
using System.Configuration;
namespace BLL
{
public class IPLocationSearch
{
private static readonly QQWry qq = new QQWry(ConfigurationManager.AppSettings["ip"] + "qqwry.dat");
public static IPLocation GetIPLocation(string ip)
{
return qq.SearchIPLocation(ip);
}
}
/*
使用方法:
例子:
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);//地区
*/
//以下是类文件
//根据LumaQQ改写而成.
/**/
///
/// QQWry 的摘要说明。
///
public class QQWry
{
//第一种模式
#region 第一种模式
/**/
///
///第一种模式
///
#endregion
private const byte REDIRECT_MODE_1 = 0x01;
//第二种模式
#region 第二种模式
/**/
///
///第二种模式
///
#endregion
private const byte REDIRECT_MODE_2 = 0x02;
//每条记录长度
#region 每条记录长度
/**/
///
///每条记录长度
///
#endregion
private const int IP_RECORD_LENGTH = 7;
//数据库文件
#region 数据库文件
/**/
///
///文件对象
///
#endregion
private FileStream ipFile;
private const string unCountry = "未知国家";
private const string unArea = "未知地区";
//索引开始位置
#region 索引开始位置
/**/
///
///索引开始位置
///
#endregion
private long ipBegin;
//索引结束位置
#region 索引结束位置
/**/
///
///索引结束位置
///
#endregion
private long ipEnd;
//IP地址对象
#region IP地址对象
/**/
///
/// IP对象
///
#endregion
private IPLocation loc;
//存储文本内容
#region 存储文本内容
/**/
///
///存储文本内容
///
#endregion
private byte[] buf;
//存储3字节
#region 存储3字节
/**/
///
///存储3字节
///
#endregion
private byte[] b3;
//存储4字节
#region 存储4字节
/**/
///
///存储4字节IP地址
///
#endregion
private byte[] b4;
//构造函数
#region 构造函数
/**/
///
///构造函数
///
///IP数据库文件绝对路径
#endregion
public QQWry(string ipfile)
{
buf = new byte[100];
b3 = new byte[3];
b4 = new byte[4];
try
{
ipFile = new FileStream(ipfile, FileMode.Open);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
ipBegin = readLong4(0);
ipEnd = readLong4(4);
loc = new IPLocation();
}
//根据IP地址搜索
#region 根据IP地址搜索
/**/
///
///搜索IP地址搜索
///
///
///
#endregion
public IPLocation SearchIPLocation(string ip)
{
//将字符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);
}
IPLocation local = null;
long offset = locateIP(IP);
if (offset != -1)
{
local = getIPLocation(offset);
}
if (local == null)
{
local = new IPLocation();
local.area = unArea;
local.country = unCountry;
}
return local;
}
//取得具体信息
#region 取得具体信息
/**/
///
///取得具体信息
///
///
///
#endregion
private IPLocation 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;
}
//取得地区信息
#region 取得地区信息
/**/
///
///读取地区名称
///
///
///
#endregion
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);
}
}
//读取字符串
#region 读取字符串
/**/
///
///读取字符串
///
///
///
#endregion
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 "";
}
//查找IP地址所在的绝对偏移量
#region 查找IP地址所在的绝对偏移量
/**/
///
///查找IP地址所在的绝对偏移量
///
///
///
#endregion
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 (bdst & 0xFF))
return 1;
else if ((bsrc ^ bdst) == 0)
return 0;
else
return -1;
}
//根据当前位置读取4字节
#region 根据当前位置读取4字节
/**/
///
///从当前位置读取4字节,转换为长整型
///
///
///
#endregion
private long readLong4(long offset)
{
long ret = 0;
ipFile.Position = offset;
ret |= (ipFile.ReadByte() & 0xFF);
ret |= ((ipFile.ReadByte()