using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
using System.IO;
public partial class ip_getip : System.Web.UI.Page
{
protected void Page_Load( object sender, EventArgs e)
{
for ( int i = 0; i < 100; i++)
{
int seed = Math.Abs(( int)BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0));
Random a = new Random(seed);
string ip1 = a.Next( 1, 255).ToString();
string ip2 = a.Next( 1, 255).ToString();
string ip3 = a.Next( 1, 255).ToString();
string ip4 = a.Next( 1, 255).ToString();
string ip = " 61.177.7.1 ";
string c2 = IpSearch.GetAddressWithIP(ip) == "" ? " 未知地址 " : IpSearch.GetAddressWithIP(ip);
Response.Write( " IP: " + ip);
Response.Write( " 地址: " + c2 + " <br/> ");
}
}
/// <summary>
/// 获得当前页面客户端的IP
/// </summary>
/// <returns> 当前页面客户端的IP </returns>
public string GetIP()
{
string result = HttpContext.Current.Request.ServerVariables[ " REMOTE_ADDR "];
if ( string.IsNullOrEmpty(result))
result = HttpContext.Current.Request.ServerVariables[ " HTTP_X_FORWARDED_FOR "];
if ( string.IsNullOrEmpty(result))
result = HttpContext.Current.Request.UserHostAddress;
if ( string.IsNullOrEmpty(result) || !IsIP(result))
return " 127.0.0.1 ";
return result;
}
/// <summary>
/// 是否为ip
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public bool IsIP( string ip)
{
return Regex.IsMatch(ip, @" ^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$ ");
}
}
/// <summary>
/// 判断IP归属地类
/// </summary>
public class IpSearch
{
/// <summary>
/// 获得当前绝对路径
/// </summary>
/// <param name="strPath"> 指定的路径 </param>
/// <returns> 绝对路径 </returns>
public static string GetMapPath( string strPath)
{
if (HttpContext.Current != null)
{
return HttpContext.Current.Server.MapPath(strPath);
}
else // 非web程序引用
{
strPath = strPath.Replace( " / ", " \\ ");
if (strPath.StartsWith( " \\ "))
{
strPath = strPath.Substring(strPath.IndexOf( ' \\ ', 1)).TrimStart( ' \\ ');
}
return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
}
}
/// <summary>
/// 返回文件是否存在
/// </summary>
/// <param name="filename"> 文件名 </param>
/// <returns> 是否存在 </returns>
public static bool FileExists( string filename)
{
return System.IO.File.Exists(filename);
}
private static object lockHelper = new object();
static PHCZIP pcz = new PHCZIP();
static string filePath = "";
static bool fileIsExsit = true;
static IpSearch()
{
string ipdatadir = " ~/ip ";
filePath = GetMapPath(ipdatadir + " /ipdata.config "); //qqwry.dat直接改名即可
fileIsExsit = FileExists(filePath);
if (fileIsExsit)
{
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;
}
}
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();
}
return country + " " + area;
}
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);
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.GetEncoding( " GB2312 ").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++)
{
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);
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
using System.IO;
public partial class ip_getip : System.Web.UI.Page
{
protected void Page_Load( object sender, EventArgs e)
{
for ( int i = 0; i < 100; i++)
{
int seed = Math.Abs(( int)BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0));
Random a = new Random(seed);
string ip1 = a.Next( 1, 255).ToString();
string ip2 = a.Next( 1, 255).ToString();
string ip3 = a.Next( 1, 255).ToString();
string ip4 = a.Next( 1, 255).ToString();
string ip = " 61.177.7.1 ";
string c2 = IpSearch.GetAddressWithIP(ip) == "" ? " 未知地址 " : IpSearch.GetAddressWithIP(ip);
Response.Write( " IP: " + ip);
Response.Write( " 地址: " + c2 + " <br/> ");
}
}
/// <summary>
/// 获得当前页面客户端的IP
/// </summary>
/// <returns> 当前页面客户端的IP </returns>
public string GetIP()
{
string result = HttpContext.Current.Request.ServerVariables[ " REMOTE_ADDR "];
if ( string.IsNullOrEmpty(result))
result = HttpContext.Current.Request.ServerVariables[ " HTTP_X_FORWARDED_FOR "];
if ( string.IsNullOrEmpty(result))
result = HttpContext.Current.Request.UserHostAddress;
if ( string.IsNullOrEmpty(result) || !IsIP(result))
return " 127.0.0.1 ";
return result;
}
/// <summary>
/// 是否为ip
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public bool IsIP( string ip)
{
return Regex.IsMatch(ip, @" ^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$ ");
}
}
/// <summary>
/// 判断IP归属地类
/// </summary>
public class IpSearch
{
/// <summary>
/// 获得当前绝对路径
/// </summary>
/// <param name="strPath"> 指定的路径 </param>
/// <returns> 绝对路径 </returns>
public static string GetMapPath( string strPath)
{
if (HttpContext.Current != null)
{
return HttpContext.Current.Server.MapPath(strPath);
}
else // 非web程序引用
{
strPath = strPath.Replace( " / ", " \\ ");
if (strPath.StartsWith( " \\ "))
{
strPath = strPath.Substring(strPath.IndexOf( ' \\ ', 1)).TrimStart( ' \\ ');
}
return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
}
}
/// <summary>
/// 返回文件是否存在
/// </summary>
/// <param name="filename"> 文件名 </param>
/// <returns> 是否存在 </returns>
public static bool FileExists( string filename)
{
return System.IO.File.Exists(filename);
}
private static object lockHelper = new object();
static PHCZIP pcz = new PHCZIP();
static string filePath = "";
static bool fileIsExsit = true;
static IpSearch()
{
string ipdatadir = " ~/ip ";
filePath = GetMapPath(ipdatadir + " /ipdata.config "); //qqwry.dat直接改名即可
fileIsExsit = FileExists(filePath);
if (fileIsExsit)
{
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;
}
}
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();
}
return country + " " + area;
}
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);
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.GetEncoding( " GB2312 ").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++)
{
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);
}
}
}
将地址库转SQL:
http://www.cnblogs.com/hejunrex/archive/2011/11/28/2266055.html