public class IpHelper
{
// 核心方法:IP搜索
/// <summary>
/// 查找IP所屬地區,確保web.config存在IPData或者BackIpData配置節
/// </summary>
/// <param name="ips">IP</param>
/// <returns></returns>
public static IpLocation GetIpLocation(string ips)
{
string fn =HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["IPData"]);
string backData = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["BackIpData"]);
if (!File.Exists(fn))
{
if (!File.Exists(backData))
{
throw new Exception("文件不存在");
}
fn = backData;
}
FileStream fs = new FileStream(fn, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader fp = new BinaryReader(fs);
//讀文件頭,獲取首末記錄偏移量
int fo = fp.ReadInt32();
int lo = fp.ReadInt32();
//IP值
uint ipv = IpStringToInt(ips);
// 獲取IP索引記錄偏移值
int rcOffset = getIndexOffset(fs, fp, fo, lo, ipv);
fs.Seek(rcOffset, System.IO.SeekOrigin.Begin);
IpLocation ipl;
if (rcOffset >= 0)
{
fs.Seek(rcOffset, System.IO.SeekOrigin.Begin);
//讀取開頭IP值
ipl.IpStart = fp.ReadUInt32();
//轉到記錄體
fs.Seek(ReadInt24(fp), System.IO.SeekOrigin.Begin);
//讀取結尾IP值
ipl.IpEnd = fp.ReadUInt32();
ipl.Country = GetString(fs, fp);
ipl.City = GetString(fs, fp);
}
else
{
//沒找到
ipl.IpStart = 0;
ipl.IpEnd = 0;
ipl.Country = "未知國家";
ipl.City = "未知地址";
}
fp.Close();
fs.Close();
return ipl;
}
// 函數功能: 采用“二分法”搜索索引區, 定位IP索引記錄位置
private static int getIndexOffset(FileStream fs, BinaryReader fp, int _fo, int _lo, uint ipv)
{
int fo = _fo, lo = _lo;
int mo; //中間偏移量
uint mv; //中間值
uint fv, lv; //邊界值
uint llv; //邊界末末值
fs.Seek(fo, System.IO.SeekOrigin.Begin);
fv = fp.ReadUInt32();
fs.Seek(lo, System.IO.SeekOrigin.Begin);
lv = fp.ReadUInt32();
//臨時作它用,末記錄體偏移量
mo = ReadInt24(fp);
fs.Seek(mo, System.IO.SeekOrigin.Begin);
llv = fp.ReadUInt32();
//邊界檢測處理
if (ipv < fv)
return -1;
else if (ipv > llv)
return -1;
//使用"二分法"確定記錄偏移量
&nb