IP定位 已经不是什么新的技术,但是在做项目中却会常常用到。找网上找了许久,也做了许多的实验,觉得QQwry.dat,很很好用的,作者也提供了开发的源码和大家分享。 在这里感谢作者。我在项目中也用到了ip定位,写了代码,希望能给没有用过的朋友有所帮助。QQ 纯真IP 数据库 下载地址QQWry.dat

直接上代码 :

IPScanner.cs

public class IPScanner
{

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 IPScanner(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());
}
public IPLocation Query(string ip)
{
if (!regex.Match(ip).Success)
{
ip = "300.300.300.300";
}
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 = "未知的IP地址";
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);
}
}
}
}

public class IPScanner
{ 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 IPScanner(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());
}
public IPLocation Query(string ip)
{
if (!regex.Match(ip).Success)
{
ip = "300.300.300.300";
}
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 = "未知的IP地址";
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);
}
}
}
}

IPLocation.cs

 public class IPLocation
{
public string IP { get; set; }
public string Country { get; set; }
public string Local { get; set; }
}
 public class IPLocation
{
public string IP { get; set; }
public string Country { get; set; }
public string Local { get; set; }
}

使用:

IPScanner qqWry = new IPScanner(Server.MapPath("~/Common/QQWry.dat"));

IPLocation ip = qqWry.Query("真实ip地址");

就这么简单。

IP定位 C#的更多相关文章

  1. C#调用百度高精度IP定位API通过IP获取地址

    API首页:http://lbsyun.baidu.com/index.php?title=webapi/high-acc-ip 1.申请百度账号,创建应用,获取密钥(AK) http://lbsyu ...

  2. 百度地图ip定位,不算bug的bug

    做为一个入行不足两年的菜鸟,能在博客园写下第一篇博客,是需要多大的勇气啊.主要还是怕大神们喷啊.其次自己文笔实在太差了. 哈哈~还请各位大神,口下留情啊. 首先说下我的需求:一个需要城市分站的手机站. ...

  3. openGPS.cn - 高精度IP定位原理,定位误差说明

    [ip定位历史] 关于IP定位,最早是通过运营商实现,每个运营商申请到的ip段,在某个范围内使用. 因此早期只能是国家为单位的基础数据. 对于比较大的国家,就进一步划分,比如,中国某通讯公司(不打广告 ...

  4. 百度地图IP定位,点击地图添加marker

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  5. 大数据mapreduce二分法ip定位之Python实现

    ip定位数据大约12M,采用-chacheFile 分发 文件来源https://pan.baidu.com/s/1J0pwTafHgt4T0k3vV_gC-A 格式大致格式如下: 0.0.0.0 0 ...

  6. java调用高德地图api实现通过ip定位访问者的城市

    所需东西:高德地图的key 注意:这个key是 web服务的key  和js的key不是一个key(若没有则自行创建,创建教程在文末) 高德地图的api文档:https://lbs.amap.com/ ...

  7. web端ip定位

    1/新浪定位 <script src="http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js">&l ...

  8. 有关于腾讯地图服务端IP定位接口的获取当前城市的处理

    接口说明:http://apis.map.qq.com/ws/location/v1/ip 说明里面写了ip可以缺省,然并卵,经过测试的到结果并不能获取到当前城市,理由是腾讯ip库的对应ip精度没有定 ...

  9. 根据IP定位城市

    根据IP定位城市:http://www.sucaihuo.com/js/35.html 示例:http://www.sucaihuo.com/jquery/0/35/demo/

随机推荐

  1. java.lang.InstantiationError: sun.net.ftp.FtpClient

    发送邮件功能.本地可以,测试环境上报错.是JDK  版本导致的,,本地1.6   测试环境JDK  1.7 解决办法: 1.测试环境重新配置jdk  1.6 环境.. 2.安装  JDK  1.7  ...

  2. PHP设计模式之:工厂模式

    工厂模式: 由工厂类根据参数来决定创建出哪一种产品类的实例: 工厂类是指包含了一个专门用来创建其他对象的方法的类.所谓按需分配,传入参数进行选择,返回具体的类.工厂模式的最主要作用就是对象创建的封装. ...

  3. mysql主要应用场景 转载

    前言 据说目前MySQL用户已经达千万级别了,其中不乏企业级用户.可以说是目前最为流行的开源数据库管理系统软件了.任何产品都不可能是万能的,也不可能适用于所有的应用场景.那么MySQL到底在什么场景下 ...

  4. TCPIP通信

    最近在开发TCPIP通信,封装了3个类,望各位大神指点指点. using System; using System.Collections.Generic; using System.Text; us ...

  5. 彻底删除sql2008r2

    一.    SQL2008卸载. 1.从控制面板卸载 1)点击计算机右下角“开始”,点击“控制面板” 2)点击“卸载程序”. 3)在程序列表中找到“Microsoft SQL Server 2008” ...

  6. WPF学习(一)控件的公共属性

    Visiblity控件是否可见:枚举类型:Visible表示可见.Collapsed不可见. IsEnabled:控件是否可用:bool类型. Background:背景色. FontSize:字体大 ...

  7. CURL传输与获取功能

    什么是CURL? 利用URL语法爱命令行方式下工作的文件传输工具.它支持很多协议.它支持认证功能.php中常用都实现更复杂的传输功能. 实现的功能: 1.实现远程获取和采集内容 2.实现PHP 网页版 ...

  8. hadoop namenode多次格式化后,导致datanode启动不了

    jps hadoop namenode -format dfs directory : /home/hadoop/dfs --data --current/VERSION #Wed Jul :: CS ...

  9. 【转】深入 char * ,char ** ,char a[ ] ,char *a[] 内核

    原文出处:http://blog.csdn.net/daiyutage/article/details/8604720    C语言中由于指针的灵活性,导致指针能代替数组使用,或者混合使用,这些导致了 ...

  10. CocoaPods ADD private Spec Repo

    Private Pods CocoaPods is a great tool not only for adding open source code to your project, but als ...