`
雄风铁骑
  • 浏览: 1930 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

最新IP地址数据库 二分逼近算法 高效解析800万大数据之区域分布

    博客分类:
  • c#
阅读更多

最新IP地址数据库  来自 qqzeng.com 

利用二分逼近法(bisection method) ,解析800多万IP 只需几十秒, 比较高效!

原来的顺序查找算法 效率比较低

C# code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 readonly string ipBinaryFilePath = "qqzengipdb.dat";
        readonly byte[] dataBuffer, indexBuffer;
        readonly uint[] index = new uint[256];
        readonly int dataLength;
        public IpLocation()
        {
            try
            {
                FileInfo file = new FileInfo(ipBinaryFilePath);
                dataBuffer = new byte[file.Length];
                using (var fin = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
                {
                    fin.Read(dataBuffer, 0, dataBuffer.Length);
                }                
                var offset_len = BytesToLong(dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3]); //Big Endian
                indexBuffer = new byte[offset_len];
                Array.Copy(dataBuffer, 4, indexBuffer, 0, offset_len);
                dataLength = (int)offset_len;
                for (int loop = 0; loop < 256; loop++)
                {
                    //索引 四字节  LITTLE_ENDIAN
                    index[loop] = BytesToLong(indexBuffer[loop * 4 + 3], indexBuffer[loop * 4 + 2], indexBuffer[loop * 4 + 1], indexBuffer[loop * 4]);
                }
            }
            catch { }
        }
 
        public string[] Find(string ip)
        {
            var ips = ip.Split('.');
            uint ip_prefix = uint.Parse(ips[0]);
            uint find_uint32 = BytesToLong(byte.Parse(ips[0]), byte.Parse(ips[1]), byte.Parse(ips[2]), byte.Parse(ips[3]));//BIG_ENDIAN
           
            // LITTLE_ENDIAN
            int max_len = 0;       
            int resultOffset =-1;
            int resultLegth =-1;
             
            uint start = index[ip_prefix] * 8 + 1024;
            if (ip_prefix != 255)
            {
                max_len = (int)index[ip_prefix + 1] * 8 + 1024;
            }
            else
            {
                max_len = (int)index[255] * 8 + 1024+1;
            }
    
            for (; start < max_len; start += 8)
            {
                // 前四位 结束ip   后三位 偏移  最后一位 内容长度 
                uint endipNum = BytesToLong(indexBuffer[start + 0], indexBuffer[start + 1], indexBuffer[start + 2], indexBuffer[start + 3]);//BIG_ENDIAN
                if (endipNum >= find_uint32)
                {
                    resultOffset =(int) BytesToLong((byte)0, indexBuffer[start + 6], indexBuffer[start + 5], indexBuffer[start + 4]);//LITTLE_ENDIAN
                    resultLegth = 0xFF & indexBuffer[start + 7];// 长度
                    break;
                }             
            }
            if (resultOffset==-1||resultLegth==-1)
            {
                return new string[] {"N/A"};
            }
            var areaBytes = new byte[resultLegth];
            Array.Copy(dataBuffer, dataLength + resultOffset - 1024, areaBytes, 0, resultLegth);
            return Encoding.UTF8.GetString(areaBytes).Split(' ');
        }
 
      
        private static uint BytesToLong(byte a, byte b, byte c, byte d)
        {
            
            return ((uint)a << 24) | ((uint)b << 16) | ((uint)c << 8) | (uint)d;
        }
 
 
        public static string long2IP(long longIP)
        {
            StringBuilder sb = new StringBuilder("");
            sb.Append(longIP >> 24);
            sb.Append(".");
            //将高8位置0,然后右移16为
 
            sb.Append((longIP & 0x00FFFFFF) >> 16);
            sb.Append(".");
 
            sb.Append((longIP & 0x0000FFFF) >> 8);
            sb.Append(".");
            sb.Append((longIP & 0x000000FF));
 
            return sb.ToString();
 
        }
  
    }




改进版 采用二分逼近 算法(类似二分查找,但又不同)  性能提升很大

C# code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 public string[] Find(string ip)
        {
            var ips = ip.Split('.');
            uint ip_prefix = uint.Parse(ips[0]);
            uint find_uint32 = BytesToLong(byte.Parse(ips[0]), byte.Parse(ips[1]), byte.Parse(ips[2]), byte.Parse(ips[3]));//BIG_ENDIAN
            uint max_len = 0;
            int resultOffset = -1;
            int resultLegth = -1;
            uint start = index[ip_prefix];
            if (ip_prefix != 255)
            {
                max_len = index[ip_prefix + 1];
            }
            else
            {
                max_len = index[255];
            }
            uint num = max_len - start;
            uint my_index = BinarySearch(start, max_len, find_uint32);
            start = my_index * 8 + 1024;
            resultOffset = (int)BytesToLong((byte)0, indexBuffer[start + 6], indexBuffer[start + 5], indexBuffer[start + 4]);//LITTLE_ENDIAN
            resultLegth = 0xFF & indexBuffer[start + 7];// 长度
 
            if (resultOffset == -1 || resultLegth == -1)
            {
                return new string[] { "N/A" };
            }
            var areaBytes = new byte[resultLegth];
            Array.Copy(dataBuffer, dataLength + resultOffset - 1024, areaBytes, 0, resultLegth);
            return Encoding.UTF8.GetString(areaBytes).Split(' ');
        }
 
 
 
        /// <summary>
        /// 二分逼近
        /// </summary>
        public uint BinarySearch(uint low, uint high, uint k)
        {
            uint M = 0;
            while (low <= high)
            {
                uint mid = (low + high) / 2;
                uint endipNum = GetStartIp(mid);
                if (endipNum >= k)
                {
                    M = mid; //mid有可能是解
                    high = mid - 1;
                }
                else
                    low = mid + 1;
            }
            return M;
        }



有了上面高效算法  解析出来800多万数据 也很快   再用一个简单的ling 统计一下即可

C# code?
1
2
3
  var cn_result= from r in list
                        group r by r.cn into g
                        select new { key = g.Key, cnt = g.Count() };


 800多万数据  统计组图  






微信



1
1
分享到:
评论

相关推荐

    IP地址解析数据库,很好用噢

    IP地址解析数据库是一种用于将互联网上的IP地址转换为地理信息的工具,这在各种网络服务和数据分析中非常有用。GeoLite2-City.mmdb是MaxMind公司提供的一个免费的IP地址数据库,它能够将IPv4和IPv6地址映射到对应的...

    最新IP地址数据库

    最新IP地址数据库 ,可以做各种数据开发的原始资源

    最全ip地址MYSQL数据库

    总的来说,"最全IP地址MYSQL数据库"是一个实用的工具,它结合了MySQL的强大查询能力与IP地址地理位置信息,为开发者和网络管理员提供了便利,使得能够快速高效地处理和解析IP地址数据,进一步提升服务质量和用户体验...

    纯真IP库的读取方法 IP地址数据库

    - 实现二分查找算法,输入一个IP地址,返回其所在IP段的索引。 - 设计解码函数,根据数据文件的编码规则,将字节流转换为字符串。 - 提供查询接口,接受IP地址,通过二分查找和解码,返回地理位置信息。 5. 使用...

    IP地址数据库(国内,国外)

    IP地址数据库是网络管理、数据分析和网络安全等领域的重要资源,它包含全球范围内IP地址的信息,用于定位、识别网络设备和流量。本压缩包提供的"IP地址数据库(国内,国外)"涵盖了国内外的IP数据,更新频率为每月一...

    最新全球IP地址数据库,可导入mysql 。

    标题中的“最新全球IP地址数据库,可导入mysql”指出这是一个包含全球IP地址信息的数据集合,且数据格式可以被MySQL数据库管理系统所使用。这意味着这个数据库很可能包含了互联网上所有或大部分活跃的IP地址,按照...

    2010年最新IP地址数据库

    标题中的“2010年最新IP地址数据库”指的是一个包含当时最新IP地址信息的数据集合,主要用于网络管理和分析。在互联网中,IP地址是每个设备在网络上的唯一标识,由四段数字组成,每段数字范围在0到255之间,以点分十...

    IP地址数据库

    包含全球IP地址数据。

    IP地址数据库大全-ACCESS数据库

    这个IP地址数据库大全提供了一个全面的资源,包含了全球各地的IP地址信息,旨在帮助用户快速、准确地定位和查询IP地址对应的地理区域。本文将深入探讨IP地址的基本概念、IP地址与地理位置的关系,以及如何利用ACCESS...

    最新国内IP地址数据库精简版,仅保留省份和城市(SQL版)

    国内最新IP地址数据库,可导入MYSQL,SQL查询方法: 首先把ip地址转换为整型数值,PHP可使用ip2long函数, SQL语句如下: SELECT * FROM `ip2city` WHERE '{转换后的ip整型数值}' BETWEEN `start_ip` AND `end_ip` ...

    java读取纯真IP地址数据库

    - 由于IP地址按顺序排列,可以利用二分查找算法高效地找到目标IP地址所在的位置。 - 实现二分查找时,注意边界条件的处理和递归终止条件。 6. **数据结构设计**: - 为了方便存储和查找,可以创建一个自定义的...

    ip数据库ip数据库ip数据库

    IP数据库包含了全球或特定区域内的IPv4或IPv6地址,与之对应的国家、地区、城市等地理信息,以及可能的ISP(互联网服务提供商)信息。这种数据库可以方便地进行IP地址查询,快速获取对应IP的相关详情。 描述虽然...

    IP地址数据库(QQIP地址) 纯真IP地址数据库

    IP地址数据库(QQIP地址) 纯真IP地址数据库.rar,全国IP地址数据库文件,比较详细的。

    全世界最新IP地址数据库 2017年12月数据

    全世界最新IP地址数据库,2017年12月最新数据,可用于网站IP地址查询,无错漏无重复。

    C#操作IP地址数据库源码(完整版)

    总之,C#操作IP地址数据库源码涉及到的主要知识点包括:IP地址的处理(IPAddress类)、数据结构的选择(哈希表或二分查找)、文件读取(StreamReader或BinaryReader)、数据解析、查询算法实现(如哈希查找或二分...

    IP地址数据库-本地查询工具v1.0

    总结来说,“IP地址数据库-本地查询工具v1.0”是一款高效、实用的本地化IP查询工具,它整合了最新的IP地址数据,能快速准确地提供IP地址的地理定位和网络信息,对网络管理和安全研究具有重要意义。通过直接在本地...

    IP地址数据库(iP138测试版_txt)

    iP数据库字段说明(从左到右): 1.起始iP iP地址的长整形格式 2.结束iP iP地址的长整形格式 3.起始iP 完整iP地址 4.结束iP 完整iP地址 5.国家 6.省 7.市 8.运营商名称 9.邮政编码 10.地区区号

    纯真ip地址数据库(20110530)mysql版sql格式

    《纯真IP地址数据库(20110530)MySQL版SQL格式》 IP地址数据库是网络管理、网络安全及数据分析等领域不可或缺的工具。本文将深入探讨纯真IP地址数据库20110530 MySQL版,以及如何利用.sql格式的文件进行数据导入。 ...

Global site tag (gtag.js) - Google Analytics