手机
当前位置:查字典教程网 >编程开发 >C#教程 >C#读取QQ纯真IP数据库QQWry.Dat的代码
C#读取QQ纯真IP数据库QQWry.Dat的代码
摘要:纯真版QQIP数据库复制代码代码如下:usingSystem;usingSystem.Collections.Generic;usingSy...

纯真版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改写而成.

/**/

///<summary>

/// QQWry 的摘要说明。

///</summary>

public class QQWry

{

//第一种模式

#region 第一种模式

/**/

///<summary>

///第一种模式

///</summary>

#endregion

private const byte REDIRECT_MODE_1 = 0x01;

//第二种模式

#region 第二种模式

/**/

///<summary>

///第二种模式

///</summary>

#endregion

private const byte REDIRECT_MODE_2 = 0x02;

//每条记录长度

#region 每条记录长度

/**/

///<summary>

///每条记录长度

///</summary>

#endregion

private const int IP_RECORD_LENGTH = 7;

//数据库文件

#region 数据库文件

/**/

///<summary>

///文件对象

///</summary>

#endregion

private FileStream ipFile;

private const string unCountry = "未知国家";

private const string unArea = "未知地区";

//索引开始位置

#region 索引开始位置

/**/

///<summary>

///索引开始位置

///</summary>

#endregion

private long ipBegin;

//索引结束位置

#region 索引结束位置

/**/

///<summary>

///索引结束位置

///</summary>

#endregion

private long ipEnd;

//IP地址对象

#region IP地址对象

/**/

///<summary>

/// IP对象

///</summary>

#endregion

private IPLocation loc;

//存储文本内容

#region 存储文本内容

/**/

///<summary>

///存储文本内容

///</summary>

#endregion

private byte[] buf;

//存储3字节

#region 存储3字节

/**/

///<summary>

///存储3字节

///</summary>

#endregion

private byte[] b3;

//存储4字节

#region 存储4字节

/**/

///<summary>

///存储4字节IP地址

///</summary>

#endregion

private byte[] b4;

//构造函数

#region 构造函数

/**/

///<summary>

///构造函数

///</summary>

///<param name="ipfile">IP数据库文件绝对路径</param>

#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地址搜索

/**/

///<summary>

///搜索IP地址搜索

///</summary>

///<param name="ip"></param>

///<returns></returns>

#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 取得具体信息

/**/

///<summary>

///取得具体信息

///</summary>

///<param name="offset"></param>

///<returns></returns>

#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 取得地区信息

/**/

///<summary>

///读取地区名称

///</summary>

///<param name="offset"></param>

///<returns></returns>

#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 读取字符串

/**/

///<summary>

///读取字符串

///</summary>

///<param name="offset"></param>

///<returns></returns>

#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地址所在的绝对偏移量

/**/

///<summary>

///查找IP地址所在的绝对偏移量

///</summary>

///<param name="ip"></param>

///<returns></returns>

#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 <= 0)

return m;

else

return -1;

}

//读出4字节的IP地址

#region 读出4字节的IP地址

/**/

///<summary>

///从当前位置读取四字节,此四字节是IP地址

///</summary>

///<param name="offset"></param>

///<param name="ip"></param>

#endregion

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;

}

//比较IP地址是否相同

#region 比较IP地址是否相同

/**/

///<summary>

///比较IP地址是否相同

///</summary>

///<param name="ip"></param>

///<param name="beginIP"></param>

///<returns>0:相等,1:ip大于beginIP,-1:小于</returns>

#endregion

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;

}

//比较两个字节是否相等

#region 比较两个字节是否相等

/**/

///<summary>

///比较两个字节是否相等

///</summary>

///<param name="bsrc"></param>

///<param name="bdst"></param>

///<returns></returns>

#endregion

private int compareByte(byte bsrc, byte bdst)

{

if ((bsrc & 0xFF) > (bdst & 0xFF))

return 1;

else if ((bsrc ^ bdst) == 0)

return 0;

else

return -1;

}

//根据当前位置读取4字节

#region 根据当前位置读取4字节

/**/

///<summary>

///从当前位置读取4字节,转换为长整型

///</summary>

///<param name="offset"></param>

///<returns></returns>

#endregion

private long readLong4(long offset)

{

long ret = 0;

ipFile.Position = offset;

ret |= (ipFile.ReadByte() & 0xFF);

ret |= ((ipFile.ReadByte() << 8) & 0xFF00);

ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);

ret |= ((ipFile.ReadByte() << 24) & 0xFF000000);

return ret;

}

//根据当前位置,读取3字节

#region 根据当前位置,读取3字节

/**/

///<summary>

///根据当前位置,读取3字节

///</summary>

///<param name="offset"></param>

///<returns></returns>

#endregion

private long readLong3(long offset)

{

long ret = 0;

ipFile.Position = offset;

ret |= (ipFile.ReadByte() & 0xFF);

ret |= ((ipFile.ReadByte() << 8) & 0xFF00);

ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);

return ret;

}

//从当前位置读取3字节

#region 从当前位置读取3字节

/**/

///<summary>

///从当前位置读取3字节

///</summary>

///<returns></returns>

#endregion

private long readLong3()

{

long ret = 0;

ret |= (ipFile.ReadByte() & 0xFF);

ret |= ((ipFile.ReadByte() << 8) & 0xFF00);

ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);

return ret;

}

//取得begin和end之间的偏移量

#region 取得begin和end之间的偏移量

/**/

///<summary>

///取得begin和end中间的偏移

///</summary>

///<param name="begin"></param>

///<param name="end"></param>

///<returns></returns>

#endregion

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;

}

} //class QQWry

public class IPLocation

{

public String country;

public String area;

public IPLocation()

{

country = area = "";

}

public IPLocation getCopy()

{

IPLocation ret = new IPLocation();

ret.country = country;

ret.area = area;

return ret;

}

}

}

【C#读取QQ纯真IP数据库QQWry.Dat的代码】相关文章:

C#数据结构之循环链表的实例代码

c# 数据库的 sql 参数封装类的编写

C#连接Oracle数据库的实例方法

c#给图片添加文字的代码小结

c# 获取网页中指定的字符串信息的实例代码

C# 全角和半角转换以及判断的简单代码

C#反射在实际应用中的实例代码

C#组合函数的使用详解

C#实现路由器断开连接,更改公网ip的实例代码

C#常用的数据格式转换汇总

精品推荐
分类导航