
Code
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace QQWry.NET


{

public class IPLocation

{
//示例:
//QQWryLocator qQWryLocator = new QQWryLocator("qqwry.dat");
//IPLocation iPLocation = qQWryLocator.Query("220.168.77.47");


/**//// <summary>
/// 所查询的IP
/// </summary>

public string IP
{ get; set; }

/**//// <summary>
/// IP对应的地理位置(大地名)
/// </summary>

public string Country
{ get; set; }

/**//// <summary>
/// IP对应的地理位置(小地名)
/// </summary>

public string Local
{ get; set; }
}
public class QQWryLocator

{
private byte[] data;
Regex regex = new Regex(@"(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))");
long firstStartIpOffset;
long lastStartIpOffset;
long ipCount;

public long Count
{ get
{ return ipCount; } }

public QQWryLocator(string dataPath)

{
using (FileStream fs = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read))

{
data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
}
byte[] buffer = new byte[8];
Array.Copy(data, 0, buffer, 0, 8);
firstStartIpOffset = ((buffer[0] + (buffer[1] * 0x100)) + ((buffer[2] * 0x100) * 0x100)) + (((buffer[3] * 0x100) * 0x100) * 0x100);
lastStartIpOffset = ((buffer[4] + (buffer[5] * 0x100)) + ((buffer[6] * 0x100) * 0x100)) + (((buffer[7] * 0x100) * 0x100) * 0x100);
ipCount = Convert.ToInt64((double)(((double)(lastStartIpOffset - firstStartIpOffset)) / 7.0));

if (ipCount <= 1L)

{
throw new ArgumentException("ip FileDataError");
}
}

private static long IpToInt(string ip)

{

char[] separator = new char[]
{ '.' };
if (ip.Split(separator).Length == 3)

{
ip = ip + ".0";
}
string[] strArray = ip.Split(separator);
long num2 = ((long.Parse(strArray[0]) * 0x100L) * 0x100L) * 0x100L;
long num3 = (long.Parse(strArray[1]) * 0x100L) * 0x100L;
long num4 = long.Parse(strArray[2]) * 0x100L;
long num5 = long.Parse(strArray[3]);
return (((num2 + num3) + num4) + num5);
}

private static string IntToIP(long ip_Int)

{
long num = (long)((ip_Int & 0xff000000L) >> 0x18);
if (num < 0L)

{
num += 0x100L;
}
long num2 = (ip_Int & 0xff0000L) >> 0x10;
if (num2 < 0L)

{
num2 += 0x100L;
}
long num3 = (ip_Int & 0xff00L) >> 8;
if (num3 < 0L)

{
num3 += 0x100L;
}
long num4 = ip_Int & 0xffL;
if (num4 < 0L)

{
num4 += 0x100L;
}
return (num.ToString() + "." + num2.ToString() + "." + num3.ToString() + "." + num4.ToString());
}


/**//// <summary>
/// 查询IP对应地理位置信息
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public IPLocation Query(string ip)

{
if (!regex.Match(ip).Success)

{
throw new ArgumentException("IP格式错误");
}

IPLocation ipLocation = new IPLocation()
{ IP = ip };
long intIP = IpToInt(ip);
if ((intIP >= IpToInt("127.0.0.1") && (intIP <= IpToInt("127.255.255.255"))))

{
ipLocation.Country = "本机内部环回地址";
ipLocation.Local = "";
}
else

{
if ((((intIP >= IpToInt("0.0.0.0")) && (intIP <= IpToInt("2.255.255.255"))) || ((intIP >= IpToInt("64.0.0.0")) && (intIP <= IpToInt("126.255.255.255")))) ||
((intIP >= IpToInt("58.0.0.0")) && (intIP <= IpToInt("60.255.255.255"))))

{
ipLocation.Country = "网络保留地址";
ipLocation.Local = "";
}
}
long right = ipCount;
long left = 0L;
long middle = 0L;
long startIp = 0L;
long endIpOff = 0L;
long endIp = 0L;
int countryFlag = 0;
while (left < (right - 1L))

{
middle = (right + left) / 2L;
startIp = GetStartIp(middle, out endIpOff);
if (intIP == startIp)

{
left = middle;
break;
}
if (intIP > startIp)

{
left = middle;
}
else

{
right = middle;
}
}
startIp = GetStartIp(left, out endIpOff);
endIp = GetEndIp(endIpOff, out countryFlag);
if ((startIp <= intIP) && (endIp >= intIP))

{
string local;
ipLocation.Country = GetCountry(endIpOff, countryFlag, out local);
ipLocation.Local = local;
}
else

{
ipLocation.Country = "未知";
ipLocation.Local = "";
}
return ipLocation;
}

private long GetStartIp(long left, out long endIpOff)

{
long leftOffset = firstStartIpOffset + (left * 7L);
byte[] buffer = new byte[7];
Array.Copy(data, leftOffset, buffer, 0, 7);
endIpOff = (Convert.ToInt64(buffer[4].ToString()) + (Convert.ToInt64(buffer[5].ToString()) * 0x100L)) + ((Convert.ToInt64(buffer[6].ToString()) * 0x100L) * 0x100L);
return ((Convert.ToInt64(buffer[0].ToString()) + (Convert.ToInt64(buffer[1].ToString()) * 0x100L)) + ((Convert.ToInt64(buffer[2].ToString()) * 0x100L) * 0x100L)) + (((Convert.ToInt64(buffer[3].ToString()) * 0x100L) * 0x100L) * 0x100L);
}

private long GetEndIp(long endIpOff, out int countryFlag)

{
byte[] buffer = new byte[5];
Array.Copy(data, endIpOff, buffer, 0, 5);
countryFlag = buffer[4];
return ((Convert.ToInt64(buffer[0].ToString()) + (Convert.ToInt64(buffer[1].ToString()) * 0x100L)) + ((Convert.ToInt64(buffer[2].ToString()) * 0x100L) * 0x100L)) + (((Convert.ToInt64(buffer[3].ToString()) * 0x100L) * 0x100L) * 0x100L);
}


/**//// <summary>
/// Gets the country.
/// </summary>
/// <param name="endIpOff">The end ip off.</param>
/// <param name="countryFlag">The country flag.</param>
/// <param name="local">The local.</param>
/// <returns>country</returns>
private string GetCountry(long endIpOff, int countryFlag, out string local)

{
string country = "";
long offset = endIpOff + 4L;
switch (countryFlag)

{
case 1:
case 2:
country = GetFlagStr(ref offset, ref countryFlag, ref endIpOff);
offset = endIpOff + 8L;
local = (1 == countryFlag) ? "" : GetFlagStr(ref offset, ref countryFlag, ref endIpOff);
break;
default:
country = GetFlagStr(ref offset, ref countryFlag, ref endIpOff);
local = GetFlagStr(ref offset, ref countryFlag, ref endIpOff);
break;
}
return country;
}

private string GetFlagStr(ref long offset, ref int countryFlag, ref long endIpOff)

{
int flag = 0;
byte[] buffer = new byte[3];

while (true)

{
//用于向前累加偏移量
long forwardOffset = offset;
flag = data[forwardOffset++];
//没有重定向
if (flag != 1 && flag != 2)

{
break;
}
Array.Copy(data, forwardOffset, buffer, 0, 3);
forwardOffset += 3;
if (flag == 2)

{
countryFlag = 2;
endIpOff = offset - 4L;
}
offset = (Convert.ToInt64(buffer[0].ToString()) + (Convert.ToInt64(buffer[1].ToString()) * 0x100L)) + ((Convert.ToInt64(buffer[2].ToString()) * 0x100L) * 0x100L);
}
if (offset < 12L)

{
return "";
}
return GetStr(ref offset);
}

private string GetStr(ref long offset)

{
byte lowByte = 0;
byte highByte = 0;
StringBuilder stringBuilder = new StringBuilder();
byte[] bytes = new byte[2];
Encoding encoding = Encoding.GetEncoding("GB2312");
while (true)

{
lowByte = data[offset++];
if (lowByte == 0)

{
return stringBuilder.ToString();
}
if (lowByte > 0x7f)

{
highByte = data[offset++];
bytes[0] = lowByte;
bytes[1] = highByte;
if (highByte == 0)

{
return stringBuilder.ToString();
}
stringBuilder.Append(encoding.GetString(bytes));
}
else

{
stringBuilder.Append((char)lowByte);
}
}
}
}
}

posted @
2009-10-27 10:12
随便取个名字算了
阅读(
380)
评论()
收藏
举报