http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 9962|回复: 2

[网络] 自动提取IP归属地的帮助类IpSearchHelper(CZ88.NET纯真IP库)

[复制链接]
发表于 2021-8-17 14:20:05 | 显示全部楼层 |阅读模式
我相信大家在很多使用场景中都会用到IP归属在这个功能
但大多是在线的收费功能
今天给大家介绍一个免费的方法,并且可以在本地长期使用

链接:https://pan.baidu.com/s/1dZmpJi2c38-_Vk21WL5z-w
提取码:iqpa


不费话直接上类,安装好之后直接使用如下类进行访问 即可。

[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace tools
{
    /// <summary>
    /// 查询IP对应的归属地区
    /// 作者:苏飞
    /// 开发时间:2019-09-24 
    /// 更新网址:[url=http://wwww.sufeinet.com]http://wwww.sufeinet.com[/url]
    /// </summary>
    public class IpSearchHelper
    {
        FileStream ipFile;
        long ip;
        string ipfilePath;

        ///<summary>
        /// 构造函数
        ///</summary>
        ///<param name="ipfilePath">纯真IP数据库路径</param>
        public IpSearchHelper()
        {
            
            this.ipfilePath = ConfigHelper.As_GetValue("ipsearchpath");
        }

        ///<summary>
        /// 获取指定IP所在地理位置
        ///</summary>
        ///<param name="strIP">要查询的IP地址</param>
        ///<returns></returns>
        public IPLocation GetIPLocation(string strIP)
        {
            IPLocation loc = new IPLocation();

            try
            {
                ip = IPToLong(strIP);
                ipFile = new FileStream(ipfilePath, FileMode.Open, FileAccess.Read);
                long[] ipArray = BlockToArray(ReadIPBlock());
                long offset = SearchIP(ipArray, 0, ipArray.Length - 1) * 7 + 4;
                ipFile.Position += offset;//跳过起始IP
                ipFile.Position = ReadLongX(3) + 4;//跳过结束IP

                int flag = ipFile.ReadByte();//读取标志
                if (flag == 1)//表示国家和地区被转向
                {
                    ipFile.Position = ReadLongX(3);
                    flag = ipFile.ReadByte();//再读标志
                }
                long countryOffset = ipFile.Position;
                loc.country = ReadString(flag);

                if (flag == 2)
                {
                    ipFile.Position = countryOffset + 3;
                }
                flag = ipFile.ReadByte();
                loc.area = ReadString(flag);

                ipFile.Close();
                ipFile = null;

                loc.country = loc.country.Replace("CZ88.NET", string.Empty).Trim();
                loc.area = loc.area.Replace("CZ88.NET", string.Empty).Trim();
            }
            catch (Exception)
            {
                return null;
            }
            return loc;
        }
        ///<summary>
        /// 将字符串形式的IP转换位long
        ///</summary>
        ///<param name="strIP"></param>
        ///<returns></returns>
        public long IPToLong(string strIP)
        {
            byte[] ip_bytes = new byte[8];
            string[] strArr = strIP.Split(new char[] { '.' });
            for (int i = 0; i < 4; i++)
            {
                ip_bytes[i] = byte.Parse(strArr[3 - i]);
            }
            return BitConverter.ToInt64(ip_bytes, 0);
        }
        ///<summary>
        /// 将索引区字节块中的起始IP转换成Long数组
        ///</summary>
        ///<param name="ipBlock"></param>
        long[] BlockToArray(byte[] ipBlock)
        {
            long[] ipArray = new long[ipBlock.Length / 7];
            int ipIndex = 0;
            byte[] temp = new byte[8];
            for (int i = 0; i < ipBlock.Length; i += 7)
            {
                Array.Copy(ipBlock, i, temp, 0, 4);
                ipArray[ipIndex] = BitConverter.ToInt64(temp, 0);
                ipIndex++;
            }
            return ipArray;
        }
        ///<summary>
        /// 从IP数组中搜索指定IP并返回其索引
        ///</summary>
        ///<param name="ipArray">IP数组</param>
        ///<param name="start">指定搜索的起始位置</param>
        ///<param name="end">指定搜索的结束位置</param>
        ///<returns></returns>
        int SearchIP(long[] ipArray, int start, int end)
        {
            int middle = (start + end) / 2;
            if (middle == start)
                return middle;
            else if (ip < ipArray[middle])
                return SearchIP(ipArray, start, middle);
            else
                return SearchIP(ipArray, middle, end);
        }
        ///<summary>
        /// 读取IP文件中索引区块
        ///</summary>
        ///<returns></returns>
        byte[] ReadIPBlock()
        {
            long startPosition = ReadLongX(4);
            long endPosition = ReadLongX(4);
            long count = (endPosition - startPosition) / 7 + 1;//总记录数
            ipFile.Position = startPosition;
            byte[] ipBlock = new byte[count * 7];
            ipFile.Read(ipBlock, 0, ipBlock.Length);
            ipFile.Position = startPosition;
            return ipBlock;
        }
        ///<summary>
        /// 从IP文件中读取指定字节并转换位long
        ///</summary>
        ///<param name="bytesCount">需要转换的字节数,主意不要超过8字节</param>
        ///<returns></returns>
        long ReadLongX(int bytesCount)
        {
            byte[] _bytes = new byte[8];
            ipFile.Read(_bytes, 0, bytesCount);
            return BitConverter.ToInt64(_bytes, 0);
        }
        ///<summary>
        /// 从IP文件中读取字符串
        ///</summary>
        ///<param name="flag">转向标志</param>
        ///<returns></returns>
        string ReadString(int flag)
        {
            if (flag == 1 || flag == 2)//转向标志
                ipFile.Position = ReadLongX(3);
            else
                ipFile.Position -= 1;

            List<byte> list = new List<byte>();
            byte b = (byte)ipFile.ReadByte();
            while (b > 0)
            {
                list.Add(b);
                b = (byte)ipFile.ReadByte();
            }
            return Encoding.Default.GetString(list.ToArray());
        }
    }

    ///<summary>
    /// 地理位置,包括国家和地区
    ///</summary>
    public class IPLocation
    {
        public string country, area;
    }
}


使用的方法也超级简单
如下
[C#] 纯文本查看 复制代码
  Pub_IpTable_BLL bll = new Pub_IpTable_BLL();
   string city = bll.GetCityByIp("193.32.23.43");


很方便,可以看看我的在线功能进行测试
http://tool.sufeinet.com/Master/urlinfo.aspx


1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2022-5-25 17:10:43 | 显示全部楼层
站长,这个ipsearchpath 是不是qqwry.dat的完整路径,能将你的这个文件共享一下吗?
 楼主| 发表于 2022-5-25 19:59:45 | 显示全部楼层
1749483004 发表于 2022-5-25 17:10
站长,这个ipsearchpath 是不是qqwry.dat的完整路径,能将你的这个文件共享一下吗?

文章开头写的有下载链接
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-3-28 19:36

© 2014-2021

快速回复 返回顶部 返回列表