你带酒来,我有故事

判断是否为中国IP

:: 代码生涯 二十画生 1760℃ 0评论

一、利用第三方网站接口

(1) IPIP.NET
http://freeapi.ipip.net/131.230.255.255
(2)百度开放平台
http://opendata.baidu.com/api.php?query=128.199.117.130&co=&resource_id=6006&ie=utf8&oe=utf-8&format=json&qq-pf-to=pcqq.c2c
缺点:不稳定,有次数或频次的限制

二、利用ip库

亚洲所有相关分配的IP段可以从 http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest  查询。
下载下来从里面整理可以判断出是否为中国IP。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cleverli
{
    public static class IPHelper
    {
        
        private static string FILE_NAME = "delegated-apnic-latest.txt";

        // 只存放属于中国的ip段
        private static Dictionary<int, List<int[]>> chinaIps = new Dictionary<int, List<int[]>>();

        static IPHelper()
        {
            Init();
        }

        /// <summary>
        /// ip格式: add1.add2.add3.add4
        /// key为 : add1*256+add2
        /// value为int[2]: int[0]存的add3*256+add4的开始ip int[4]存的结束ip
        /// </summary>
        private static void Init()
        {
            try
            {
                // ip格式: add1.add2.add3.add4
                // key为 : add1*256+add2
                // value为int[2]: int[0]存的add3*256+add4的开始ip int[4]存的结束ip
                Dictionary<int, List<int[]>> map = new Dictionary<int, List<int[]>>();

                List<string> lines = File.ReadAllLines(FILE_NAME).ToList();
                foreach (string line in lines)
                {
                    if (line.StartsWith("apnic|CN|ipv4|"))
                    {
                        // 只处理属于中国的ipv4地址
                        string[] strs = line.Split(new string[] { "\\", "|" }, StringSplitOptions.RemoveEmptyEntries);
                        string ip = strs[3];
                        string[] add = ip.Split(new string[] { "\\", "." }, StringSplitOptions.RemoveEmptyEntries);
                        int count = int.Parse(strs[4]);

                        int startIp = int.Parse(add[0]) * 256 + int.Parse(add[1]);
                        while (count > 0)
                        {
                            if (count >= 65536)
                            {
                                // add1,add2 整段都是中国ip
                                chinaIps.Add(startIp, new List<int[]>());
                                count -= 65536;
                                startIp += 1;
                            }
                            else
                            {

                                int[] ipRange = new int[2];
                                ipRange[0] = int.Parse(add[2]) * 256 + int.Parse(add[3]);
                                ipRange[1] = ipRange[0] + count;
                                count -= count;

                                List<int[]> list = null;
                                if (map.ContainsKey(startIp))
                                {
                                    list = map[startIp];
                                }
                                if (list == null)
                                {
                                    list = new List<int[]>();
                                    map.Add(startIp, list);
                                }

                                list.Add(ipRange);



                            }
                        }
                    }
                }
                chinaIps = chinaIps.Concat(map).ToDictionary(x => x.Key, x => x.Value); ;
            }
            catch (Exception e)
            {
                //Console.WriteLine(e.Message);
                throw;
            }
        }

        /// <summary>
        /// 判断ip是否中国ip
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsChinaIp(string ip)
        {
            if (string.IsNullOrEmpty(ip))
            {
                return false;
            }
            string[] strs = ip.Split(new string[] { "\\", "." }, StringSplitOptions.RemoveEmptyEntries);
            if (strs.Length != 4)
            {
                return false;
            }
            int key = int.Parse(strs[0]) * 256 + int.Parse(strs[1]);
            List<int[]> list = null;
            if (chinaIps.ContainsKey(key))
            {
               list = chinaIps[key];
            }
            if (list == null)
            {
                return false;
            }
            if (list.Count == 0)
            {
                // 整段都是中国ip
                return true;
            }
            int ipValue = int.Parse(strs[2]) * 256 + int.Parse(strs[3]);
            foreach (int[] ipRange in list)
            {
                if (ipValue >= ipRange[0] && ipValue <= ipRange[1])
                {
                    return true;
                }
            }

            return false;
        }


    }
}
如果在判断IP属于哪个城市,可能得需要 http://dev.maxmind.com/zh-hans/geoip/geoip2/

三、源码

转载请注明:二十画生 » 判断是否为中国IP

喜欢 (22)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址