asp.net DZ论坛中根据IP地址取得所在地的代码
程序员文章站
2022-05-05 16:03:17
使用方法: 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数据库,在打包中有。打包下载
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数据库,在打包中有。打包下载