最新手机号段归属地数据库 高性能dat解析[通俗易懂]

最新手机号段归属地数据库 高性能dat解析[通俗易懂]最新手机号段数据库2019-12-01441831条记录号码归属地数据库全面准确规范字段包括省份城市运营商邮编区号等信息,对于数据分析、号码归属地查询等非常有帮助名称:手机号码归属地查询dat高效率查询内存优化版压缩:原版txt为22M,生成这种dat结构为2.66M性能:每秒解析300万+号段或者号码,简洁高效环境:CPU…

大家好,又见面了,我是你们的朋友全栈君。

 

最新 手机号段数据库  2020-08-15 458461条记录  号码归属地数据库  全面  准确  规范 
字段包括 省份 城市 运营商 邮编 区号 等信息,对于数据分析、号码归属地查询等非常有帮助

最新手机号段归属地数据库 高性能dat解析[通俗易懂]

名称:手机号码归属地查询 dat高效率查询  内存优化版
压缩:原版txt为22M,生成这种dat结构为2.66M 
性能:每秒解析300万+号段或者号码,简洁高效 
环境:CPU i7-7700K +内存16GB

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;

namespace qqzeng_phone_dat
{

    public class PhoneSearchFast
    {
        private static readonly Lazy<PhoneSearchFast> lazy = new Lazy<PhoneSearchFast>(() => new PhoneSearchFast());
        public static PhoneSearchFast Instance { get { return lazy.Value; } }
        private PhoneSearchFast()
        {
            LoadDat();
            Watch();
        }

        private string datPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"qqzeng-phone.dat");
        private DateTime lastRead = DateTime.MinValue;
        private long[,] prefmap = new long[200, 2];//  000-199


        private long[,] phonemap;

        private byte[] data;

        private long[] phoneArr;
        private string[] addrArr;
        private string[] ispArr;

        /// <summary>
        /// 初始化二进制dat数据
        /// </summary>
        /// <param name="dataPath"></param>
        /// 


        private void LoadDat()
        {
            data = File.ReadAllBytes(datPath);

            long PrefSize = BytesToLong(data[0], data[1], data[2], data[3]);
            long RecordSize = BytesToLong(data[4], data[5], data[6], data[7]);

            long descLength = BytesToLong(data[8], data[9], data[10], data[11]);
            long ispLength = BytesToLong(data[12], data[13], data[14], data[15]);

            //内容数组
            int descOffset = (int)(16 + PrefSize * 9 + RecordSize * 7);
            string descString = Encoding.UTF8.GetString(data, descOffset, (int)descLength);
            addrArr = descString.Split('&');

            //运营商数组
            int ispOffset = (int)(16 + PrefSize * 9 + RecordSize * 7 + descLength);
            string ispString = Encoding.UTF8.GetString(data, ispOffset, (int)ispLength);
            ispArr = ispString.Split('&');



            //前缀区
            int m = 0;
            for (var k = 0; k < PrefSize; k++)
            {
                int i = k * 9 + 16;
                int n = data[i];
                prefmap[n, 0] = BytesToLong(data[i + 1], data[i + 2], data[i + 3], data[i + 4]);
                prefmap[n, 1] = BytesToLong(data[i + 5], data[i + 6], data[i + 7], data[i + 8]);
                if (m < n)
                {
                    for (; m < n; m++)
                    {
                        prefmap[m, 0] = 0; prefmap[m, 1] = 0;
                    }
                    m++;
                }
                else
                {
                    m++;
                }
            }

            //索引区
            phoneArr = new long[RecordSize];
            phonemap = new long[RecordSize, 2];
            for (int i = 0; i < RecordSize; i++)
            {
                long p = 16 + PrefSize * 9 + (i * 7);
                phoneArr[i] = BytesToLong(data[p], data[1 + p], data[2 + p], data[3 + p]);
                phonemap[i, 0] = data[4 + p] + ((data[5 + p]) << 8);
                phonemap[i, 1] = data[6 + p];
            }



        }
        private void Watch()
        {
            FileInfo fi = new FileInfo(datPath);
            FileSystemWatcher watcher = new FileSystemWatcher(fi.DirectoryName)
            {
                IncludeSubdirectories = false,
                NotifyFilter = NotifyFilters.LastWrite,
                Filter = "qqzeng-phone.dat",
            };

            watcher.Changed += (s, e) =>
            {

                var lastWriteTime = File.GetLastWriteTime(datPath);

                if (lastWriteTime > lastRead)
                {
                    //延时 解决 正由另一进程使用,因此该进程无法访问此文件
                    Thread.Sleep(1000);

                    LoadDat();
                    lastRead = lastWriteTime;
                }
            };
            watcher.EnableRaisingEvents = true;
        }




        /// <summary>
        /// 号段查询
        /// </summary>
        /// <param name="phone">7位或者11位</param>
        /// <returns></returns>
        public string Query(string phone)
        {
            long pref;
            long val = PhoneToInt(phone, out pref);
            long low = prefmap[pref, 0], high = prefmap[pref, 1];
            if (high == 0)
            {
                return "";
            }
            long cur = low == high ? low : BinarySearch(low, high, val);
            if (cur != -1)
            {

                return addrArr[phonemap[cur, 0]] + "|" + ispArr[phonemap[cur, 1]];
            }
            else
            {
                return "";
            }






        }
        /// <summary>
        /// 二分算法
        /// </summary>
        private int BinarySearch(long low, long high, long key)
        {
            if (low > high)
                return -1;
            else
            {
                long mid = (low + high) / 2;
                long phoneNum = phoneArr[mid];
                if (phoneNum == key)
                    return (int)mid;
                else if (phoneNum > key)
                    return BinarySearch(low, mid - 1, key);
                else
                    return BinarySearch(mid + 1, high, key);
            }
        }



        private long PhoneToInt(string phone, out long prefix)
        {
            //最高性能
            char ch;
            long currentValue = 0;
            long prefval = 0;
            unsafe
            {
                fixed (char* name = phone)
                {
                    for (int current = 0; current < 7; current++)
                    {
                        ch = name[current];
                        int digitValue = ch - '0';
                        currentValue = (currentValue * 10) + digitValue;
                        if (current == 2)
                        {
                            prefval = currentValue;
                        }
                    }
                }
                prefix = prefval;
                return currentValue;
            }


            //prefix = Convert.ToUInt32(phone.Substring(0,3));
            //return Convert.ToUInt32(phone.Substring(0, 7)); ;
        }



        /// <summary>
        /// 字节转整形 小节序 
        /// </summary>     
        private uint BytesToLong(byte a, byte b, byte c, byte d)
        {
            return (uint)(a | (b << 8) | (c << 16) | (d << 24));
        }



    }

    /*
    (调用例子):    
    string result = PhoneSearchFast.Instance.Query("号段|号码");
   --> result="省份|城市|区号|邮编|行政区划代码|运营商"
    */
}

最新手机号段归属地数据库 高性能dat解析[通俗易懂]

 

更新历史: 

2020-08-15 458461条记录
2020-08-01 458084条记录
2020-07-15 458020条记录
2020-07-01 457441条记录
2020-06-01 454802条记录
2020-05-01 450433条记录
2020-04-01 450175条记录
2020-03-01 447897条记录
2020-01-01 442612条记录
2019-12-01 441831条记录
2019-11-01 439265条记录
2019-09-01 438615条记录
2019-08-01 437142条记录
2019-07-01 436804条记录
2019-06-01 430826条记录
2019-05-01 429052条记录
2019-04-01 424014条记录
2019-03-01 423850条记录
2019-02-01 423766条记录
2019-01-01 421973条记录
2018-12-01 415967条记录
2018-11-01 415806条记录
2018-10-01 415311条记录
2018-09-01 413015条记录
2018-08-01 411856条记录
2018-07-01 410765条记录
2018-06-01 405385条记录
2018-05-01 387892条记录
2018-03-01 382140条记录
2018-02-01 381409条记录
2018-01-01 381061条记录
2017-12-01 380357条记录
2017-11-01 369022条记录
2017-10-01 368360条记录
2017-08-01 366454条记录
2017-07-01 363952条记录
2017-06-01 362386条记录
2017-05-01 359938条记录
2017-04-01 359429条记录
2017-03-01 358215条记录
2017-02-01 358006条记录
2017-01-01 357213条记录
2016-12-01 354586条记录
2016-11-01 352898条记录
2016-10-15 352182条记录
2016-09-15 352176条记录
2016-08-15 352069条记录
2016-07-15 344348条记录
2016-06-15 343198条记录
2016-05-15 335588条记录
2016-04-15 335169条记录
2016-03-25 334447条记录
2016-03-01 331878条记录
2016-02-01 329833条记录
2016-01-01 327154条记录
2015-12-01 326601条记录
2015-11-01 326596条记录
2015-10-01 324557条记录
2015-09-01 321602条记录
2015-08-01 320432条记录
2015-07-01 320027条记录
2015-06-01 318201条记录
2015-05-01 318115条记录
2015-04-01 317191条记录
2015-03-01 312145条记录
2015-02-01 311924条记录
2015-01-01 310165条记录
2014-12-01 309966条记录
2014-11-01 309398条记录
2014-10-01 307924条记录
2014-09-01 306093条记录
2014-08-01 301472条记录
2014-07-01 303033条记录
2014-06-01 300635条记录
2014-05-01 299920条记录
2014-04-01 296010条记录
2014-03-01 289087条记录
2014-02-01 288831条记录
2014-01-01 288661条记录
2013-12-01 287379条记录
2013-11-01 286438条记录
2013-10-01 286418条记录
2013-09-01 284304条记录
2013-08-01 282136条记录
2013-07-01 281965条记录
2013-06-03 281413条记录
2013-05-03 281071条记录
2013-04-01 279680条记录
2013-03-01 276893条记录
2013-02-01 275967条记录
2013-01-01 274995条记录
2012-12-01 274832条记录
…………

 

 

Excel vlookup  函数  xls 使用

 归属地公式:=(VLOOKUP(LEFT(B2,7),号段数据库!B:D,2,0)&VLOOKUP(LEFT(B2,7),号段数据库!B:D,3,0))

 运营商公式:=(VLOOKUP(LEFT(A2,3),isp!A:B,2,0))
 运营商公式:=(VLOOKUP(LEFT(B2,7),号段数据库!B:E,4,0))

 两个列合并:=CONCATENATE(B1&C1)

 

 最新手机号段归属地数据库 高性能dat解析[通俗易懂]

开发参考 GitHub  https://github.com/zengzhan/qqzeng-ip

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163138.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • jquery tmpl遍历

    jquery tmpl遍历最近,发现大家喜欢用模板渲染一些DOM,而且常常用模板嵌套一些逻辑,看了大家用jquerytmpl较多,遇到的问题大同小异。为了避免问题重复发生,现在就个人用过的一些常用功能,作下具体介绍,主要针对遍历。其它的大家可自行看看网上教程,推荐一个:jqueryTmpl,希望对大家有所帮助1.普通数组对象的遍历,关键词{{eachArray}}、$value、$index数据格式:varperso

  • Python实现向量自回归(VAR)模型——完整步骤「建议收藏」

    废话不多说,先开始分享:1.首先啥是VAR模型,我这里简略通俗的说一下,想看代码的童鞋直接跳到第3部分就好了:以金融价格为例,传统的时间序列模型比如ARIMA,ARIMA-GARCH等,只分析价格自身的变化,模型的形式为:其中称为自身的滞后项。但是VAR模型除了分析自身滞后项的影响外,还分析其他相关因素的滞后项对未来值产生的影响,模型的形式为:其中就是其他因子的滞后项…

  • Oracle 触发器两种写法「建议收藏」

    Oracle 触发器两种写法「建议收藏」//复杂触发器,功能数据插入是触发数据联动//注意:new.DATA_REGION:=才是赋值CREATEORREPLACETRIGGERTRIGGER_NAMEBEFOREINSERTONTABLE_NAMEFOREACHROWDECLARECREATE_USER_IDVARCHAR(40);CREATE_DATEDATE;DH_EVENT_IDVARCHAR(50);DATA_REGIONVARCHAR(10);BEGI

  • 诺基亚智能手机知识大全

    诺基亚智能手机知识大全一、购买篇去买手机时的注意事项:买手机的时候一般注意一下有没有什么使用过的痕迹,看看通讯记录里有没有打过电话,有没有存乱七八糟的照片,还有看看电池触点磨损情况,按住#键5秒以上看看是否有切换线路选项;再者就是看屏幕有没有坏点,手机上的坏点可以说直接用肉眼就能看出来的,不象数码相机上的坏点还得通过软件测试,打开手机的照相机拍一张全黑的照片,在遮上一张白纸对着光照一张全白的照片(千万不要直接对着光线照

  • leetcode 两数相加(两个数相加分别叫什么)

    publicclasstest{ publicstaticvoidmain(String[]args){ System.out.println("HelloWorld!"); ListNodea=newListNode(0); ListNodeb=newListNode(0); a.val=2; a.next=newListNode(4); a….

  • qmake自定义函数「建议收藏」

    qmake自定义函数「建议收藏」使用qmake编写构建步骤时,如果较为复杂或重复的行为可以使用函数来实现。

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号