欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net DZ论坛中根据IP地址取得所在地的代码

程序员文章站 2022-09-06 21:52:58
使用方法: ipsearch.getaddresswithip("202.96.128.167")cs类代码复制代码 代码如下:using system; using sy...
使用方法: ipsearch.getaddresswithip("202.96.128.167")
cs类代码
复制代码 代码如下:

using system;
using system.data;
using system.configuration;
using system.web;
using system.web.security;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.webcontrols.webparts;
using system.web.ui.htmlcontrols;

//引入的命名空间
using system.io;

/// <summary>
/// 判断ip归属地类
/// </summary>
public class ipsearch
{
private static object lockhelper = new object();

static phczip pcz = new phczip();

static string filepath = "";

static bool fileisexsit = true;

static ipsearch()
{
filepath = httpcontext.current.server.mappath("~/ipdata.config");
pcz.setdbfilepath(filepath);
}

/// <summary>
/// 返回ip查找结果
/// </summary>
/// <param name="ipvalue">要查找的ip地址</param>
/// <returns></returns>
public static string getaddresswithip(string ipvalue)
{
lock (lockhelper)
{
string result = pcz.getaddresswithip(ipvalue.trim());

if (fileisexsit)
{
if (result.indexof("iana") >= 0)
{
return "";
}
else
{
return result;
}
}
else
{
return null;
}
}
}

/// <summary>
/// 辅助类,用于保存ip索引信息
/// </summary>
///
public class cz_index_info
{
public uint32 ipset;
public uint32 ipend;
public uint32 offset;

public cz_index_info()
{
ipset = 0;
ipend = 0;
offset = 0;
}
}

//读取纯真ip数据库类
public class phczip
{
protected bool bfilepathinitialized;
protected string filepath;
protected filestream filestrm;
protected uint32 index_set;
protected uint32 index_end;
protected uint32 index_count;
protected uint32 search_index_set;
protected uint32 search_index_end;
protected cz_index_info search_set;
protected cz_index_info search_mid;
protected cz_index_info search_end;

public phczip()
{
bfilepathinitialized = false;
}

public phczip(string dbfilepath)
{
bfilepathinitialized = false;
setdbfilepath(dbfilepath);
}

//使用二分法查找索引区,初始化查找区间
public void initialize()
{
search_index_set = 0;
search_index_end = index_count - 1;
}

//关闭文件
public void dispose()
{
if (bfilepathinitialized)
{
bfilepathinitialized = false;
filestrm.close();
//filestrm.dispose();
}

}


public bool setdbfilepath(string dbfilepath)
{
if (dbfilepath == "")
{
return false;
}

try
{
filestrm = new filestream(dbfilepath, filemode.open, fileaccess.read, fileshare.read);
}
catch
{
return false;
}
//检查文件长度
if (filestrm.length < 8)
{
filestrm.close();
//filestrm.dispose();
return false;
}
//得到第一条索引的绝对偏移和最后一条索引的绝对偏移
filestrm.seek(0, seekorigin.begin);
index_set = getuint32();
index_end = getuint32();

//得到总索引条数
index_count = (index_end - index_set) / 7 + 1;
bfilepathinitialized = true;

return true;

}

public string getaddresswithip(string ipvalue)
{
if (!bfilepathinitialized)
{
return "";
}

initialize();

uint32 ip = iptouint32(ipvalue);

while (true)
{

//首先初始化本轮查找的区间

//区间头
search_set = indexinfoatpos(search_index_set);
//区间尾
search_end = indexinfoatpos(search_index_end);

//判断ip是否在区间头内
if (ip >= search_set.ipset && ip <= search_set.ipend)
return readaddressinfoatoffset(search_set.offset);


//判断ip是否在区间尾内
if (ip >= search_end.ipset && ip <= search_end.ipend)
return readaddressinfoatoffset(search_end.offset);

//计算出区间中点
search_mid = indexinfoatpos((search_index_end + search_index_set) / 2);

//判断ip是否在中点
if (ip >= search_mid.ipset && ip <= search_mid.ipend)
return readaddressinfoatoffset(search_mid.offset);

//本轮没有找到,准备下一轮
if (ip < search_mid.ipset)
//ip比区间中点要小,将区间尾设为现在的中点,将区间缩小1倍。
search_index_end = (search_index_end + search_index_set) / 2;
else
//ip比区间中点要大,将区间头设为现在的中点,将区间缩小1倍。
search_index_set = (search_index_end + search_index_set) / 2;
}

//return "";

}

private string readaddressinfoatoffset(uint32 offset)
{
string country = "";
string area = "";
uint32 country_offset = 0;
byte tag = 0;
//跳过4字节,因这4个字节是该索引的ip区间上限。
filestrm.seek(offset + 4, seekorigin.begin);

//读取一个字节,得到描述国家信息的“寻址方式”
tag = gettag();

if (tag == 0x01)
{

//模式0x01,表示接下来的3个字节是表示偏移位置
filestrm.seek(getoffset(), seekorigin.begin);

//继续检查“寻址方式”
tag = gettag();
if (tag == 0x02)
{
//模式0x02,表示接下来的3个字节代表国家信息的偏移位置
//先将这个偏移位置保存起来,因为我们要读取它后面的地区信息。
country_offset = getoffset();
//读取地区信息(注:按照luma的说明,好像没有这么多种可能性,但在测试过程中好像有些情况没有考虑到,
//所以写了个readarea()来读取。
area = readarea();
//读取国家信息
filestrm.seek(country_offset, seekorigin.begin);
country = readstring();
}
else
{
//这种模式说明接下来就是保存的国家和地区信息了,以'\0'代表结束。
filestrm.seek(-1, seekorigin.current);
country = readstring();
area = readarea();

}
}
else if (tag == 0x02)
{
//模式0x02,说明国家信息是一个偏移位置
country_offset = getoffset();
//先读取地区信息
area = readarea();
//读取国家信息
filestrm.seek(country_offset, seekorigin.begin);
country = readstring();
}
else
{
//这种模式最简单了,直接读取国家和地区就ok了
filestrm.seek(-1, seekorigin.current);
country = readstring();
area = readarea();

}
string address = country + " " + area;
return address;

}

private uint32 getoffset()
{
byte[] tempbyte4 = new byte[4];
tempbyte4[0] = (byte)filestrm.readbyte();
tempbyte4[1] = (byte)filestrm.readbyte();
tempbyte4[2] = (byte)filestrm.readbyte();
tempbyte4[3] = 0;
return bitconverter.touint32(tempbyte4, 0);
}

protected string readarea()
{
byte tag = gettag();

if (tag == 0x01 || tag == 0x02)
{
filestrm.seek(getoffset(), seekorigin.begin);
return readstring();
}
else
{
filestrm.seek(-1, seekorigin.current);
return readstring();
}
}

protected string readstring()
{
uint32 offset = 0;
byte[] tempbytearray = new byte[256];
tempbytearray[offset] = (byte)filestrm.readbyte();
while (tempbytearray[offset] != 0x00)
{
offset += 1;
tempbytearray[offset] = (byte)filestrm.readbyte();
}
return system.text.encoding.default.getstring(tempbytearray).trimend('\0');
}

protected byte gettag()
{
return (byte)filestrm.readbyte();
}

protected cz_index_info indexinfoatpos(uint32 index_pos)
{
cz_index_info index_info = new cz_index_info();
//根据索引编号计算出在文件中在偏移位置
filestrm.seek(index_set + 7 * index_pos, seekorigin.begin);
index_info.ipset = getuint32();
index_info.offset = getoffset();
filestrm.seek(index_info.offset, seekorigin.begin);
index_info.ipend = getuint32();

return index_info;
}

/// <summary>
/// 从ip转换为int32
/// </summary>
/// <param name="ipvalue"></param>
/// <returns></returns>
public uint32 iptouint32(string ipvalue)
{
string[] ipbyte = ipvalue.split('.');
int32 nupperbound = ipbyte.getupperbound(0);
if (nupperbound != 3)
{
ipbyte = new string[4];
for (int32 i = 1; i <= 3 - nupperbound; i++)
ipbyte[nupperbound + i] = "0";
}

byte[] tempbyte4 = new byte[4];
for (int32 i = 0; i <= 3; i++)
{
//'如果是.net 2.0可以支持tryparse。
//'if not (byte.tryparse(ipbyte(i), tempbyte4(3 - i))) then
//' tempbyte4(3 - i) = &h0
//'end if
if (isnumeric(ipbyte[i]))
tempbyte4[3 - i] = (byte)(convert.toint32(ipbyte[i]) & 0xff);
}

return bitconverter.touint32(tempbyte4, 0);
}

/// <summary>
/// 判断是否为数字
/// </summary>
/// <param name="str">待判断字符串</param>
/// <returns></returns>
protected bool isnumeric(string str)
{
if (str != null && system.text.regularexpressions.regex.ismatch(str, @"^-?\d+$"))
return true;
else
return false;
}

protected uint32 getuint32()
{
byte[] tempbyte4 = new byte[4];
filestrm.read(tempbyte4, 0, 4);
return bitconverter.touint32(tempbyte4, 0);
}
}

}

需要用到ip数据库,在打包中有。打包下载