最新手机号段归属地数据库 (2021年4月版) 473101行

最新手机号段归属地数据库 (2021年4月版) 473101行最新手机号段归属地数据库(2021年4月发行版)473101行基于:最新手机号段归属地数据库名称:手机号码归属地查询dat高效率查询压缩:原版txt为25M,生成这种dat结构为2.86M性能:每秒解析300w+,简洁高效创建:qqzeng-ip开发参考手机归属地查询c#javaphp解析dat内存优化版快速内存数据库Redis版以及导入数据库mys…

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

最新手机号段归属地数据库(2021年4月发行版) 473101行
基于:最新手机号段归属地数据库 名称:手机号码归属地查询 dat高效率查询 压缩:原版txt为25M,生成这种dat结构为2.86M 性能:每秒解析300w+ ,简洁高效 创建:qqzeng-ip

开发参考  手机归属地查询 c#  java php 解析dat  内存优化版
快速内存数据Redis版   以及 导入数据库 mysql mssql 脚本

    微信小程序 号段归属地查询

最新手机号段归属地数据库 (2021年4月版) 473101行

最新手机号段归属地数据库 

最新 手机号段数据库 号码归属地数据库 移动号段 联通号段 电信号段 虚拟运营商

权威 全面 准确 规范

字段包括 省份 城市 运营商 邮编 区号 等信息,对于数据分析、号码归属地查询等非常有帮助

更新历史:

2021-04-01 473101条记录   xlsx+txt+csv+mysql+mssql
2021-03-01 472529条记录 
2021-02-01 472019条记录 
2021-01-01 471402条记录
2020-12-01 465883条记录 
2020-11-01 464737条记录 
2020-10-01 463471条记录
2020-09-01 459519条记录 
2020-08-15 458461条记录 
2020-08-01 458084条记录
2020-07-15 458020条记录
2020-07-01 457441条记录
2020-06-15 455731条记录
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-10-01 439025条记录
2019-09-01 438615条记录
2019-08-01 437124条记录
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 398209条记录
2018-04-01 387892条记录
2018-03-01 382140条记录

…………

2017-07-01 363952条记录

2017-06-01 362386条记录

2017-05-01 359938条记录

…………

2013-04-01 279680条记录

2013-03-01 276893条记录

2013-02-01 275967条记录

2013-01-01 274995条记录

2012-12-01 274832条记录

…………

 

最新手机号段归属地数据库 (2021年4月版) 473101行

移动号段:
134 135 136 137 138 139 147 148 150 151 152 157 158 159 172 178 182 183 184 187 188 195 198
联通号段:
130 131 132 145 146 155 156 166 167 171 175 176 185 186 196
电信号段:
133 149 153 173 174 177 180 181 189 191 193 199
虚拟运营商:
162 165 167 170 171

字段样例

最新手机号段归属地数据库 (2021年4月版) 473101行

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


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="省份|城市|区号|邮编|行政区划代码|运营商"
    */
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace qqzeng_phone_dat
{
    public class PhoneSearch
    {

        private Dictionary<uint, PrefixIndex> prefixDict;
        private byte[] indexBuffer;
        private byte[] data;
        long firstPhoneOffset;//索引区第一条流位置
        long lastPhoneOffset;//索引区最后一条流位置
        long prefixStartOffset;//前缀区第一条的流位置
        long prefixEndOffset;//前缀区最后一条的流位置
        long phoneCount;       //号段段数量
        long prefixCount;  //前缀数量

        /// <summary>
        /// 初始化二进制dat数据
        /// </summary>
        /// <param name="dataPath"></param>
        public PhoneSearch(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);
            }

            firstPhoneOffset = BytesToLong(data[0], data[1], data[2], data[3]);
            lastPhoneOffset = BytesToLong(data[4], data[5], data[6], data[7]);
            prefixStartOffset = BytesToLong(data[8], data[9], data[10], data[11]);
            prefixEndOffset = BytesToLong(data[12], data[13], data[14], data[15]);



            phoneCount = (lastPhoneOffset - firstPhoneOffset) / 8 + 1; //索引区块每组 8字节          
            prefixCount = (prefixEndOffset - prefixStartOffset) / 9 + 1; //前缀区块每组 9字节

            //初始化前缀对应索引区区间
            indexBuffer = new byte[prefixCount * 9];
            Array.Copy(data, prefixStartOffset, indexBuffer, 0, prefixCount * 9);
            prefixDict = new Dictionary<uint, PrefixIndex>();
            for (var k = 0; k < prefixCount; k++)
            {
                int i = k * 9;
                uint prefix = (uint)indexBuffer[i];
                long start_index = BytesToLong(indexBuffer[i + 1], indexBuffer[i + 2], indexBuffer[i + 3], indexBuffer[i + 4]);
                long end_index = BytesToLong(indexBuffer[i + 5], indexBuffer[i + 6], indexBuffer[i + 7], indexBuffer[i + 8]);
                prefixDict.Add(prefix, new PrefixIndex() { prefix = prefix, start_index = start_index, end_index = end_index });
            }

        }

        public static uint PhoneToInt(string phone, out uint prefix)
        {
            prefix = Convert.ToUInt32(phone.Substring(0, 3));
            return Convert.ToUInt32(phone.Substring(0, 7)); ;
        }

        /// <summary>
        /// 号段查询
        /// </summary>
        /// <param name="phone">7位或者11位</param>
        /// <returns></returns>
        public string Query(string phone)
        {
            uint phone_prefix_value;
            uint intPhone = PhoneToInt(phone, out phone_prefix_value);
            uint high = 0;
            uint low = 0;

            uint local_offset = 0;
            uint local_length = 0;


            if (prefixDict.ContainsKey(phone_prefix_value))
            {
                low = (uint)prefixDict[phone_prefix_value].start_index;
                high = (uint)prefixDict[phone_prefix_value].end_index;
            }
            else
            {
                return "";
            }

            uint my_index = low == high ? low : BinarySearch(low, high, intPhone);

            GetIndex(my_index, out local_offset, out local_length);

            return GetLocal(local_offset, local_length);


        }
        /// <summary>
        /// 二分算法
        /// </summary>
        public uint BinarySearch(uint low, uint high, uint k)
        {
            uint M = 0;
            while (low <= high)
            {
                uint mid = (low + high) / 2;

                uint phoneNum = GetIntPhone(mid);

                if (phoneNum >= k)
                {

                    M = mid;
                    if (mid == 0)
                    {
                        break;   //防止溢出
                    }
                    high = mid - 1;
                }
                else
                    low = mid + 1;
            }
            return M;
        }
        /// <summary>
        /// 在索引区解析
        /// </summary>
        /// <param name="left">ip第left个索引</param>
        /// <param name="startip">返回开始ip的数值</param>
        /// <param name="endip">返回结束ip的数值</param>
        /// <param name="local_offset">返回地址信息的流位置</param>
        /// <param name="local_length">返回地址信息的流长度</param>
        private void GetIndex(uint left, out uint local_offset, out uint local_length)
        {
            long left_offset = firstPhoneOffset + (left * 8);
            local_offset = (uint)data[4 + left_offset] + (((uint)data[5 + left_offset]) << 8) + (((uint)data[6 + left_offset]) << 16);
            local_length = (uint)data[7 + left_offset];
        }


        /// <summary>
        /// 返回归属地信息
        /// </summary>
        /// <param name="local_offset">地址信息的流位置</param>
        /// <param name="local_length">地址信息的流长度</param>
        /// <returns></returns>
        private string GetLocal(uint local_offset, uint local_length)
        {
            byte[] buf = new byte[local_length];
            Array.Copy(data, local_offset, buf, 0, local_length);
            return Encoding.UTF8.GetString(buf, 0, (int)local_length);

            // return Encoding.GetEncoding("GB2312").GetString(buf, 0, (int)local_length);

        }

        private uint GetIntPhone(uint left)
        {
            long left_offset = firstPhoneOffset + (left * 8);
            return BytesToLong(data[0 + left_offset], data[1 + left_offset], data[2 + left_offset], data[3 + left_offset]);

        }


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



    }

    /*
    (调用例子):
    PhoneSearch finder = new PhoneSearch("qqzeng-phone.dat");
    string result = finder.Query("号段或者号码");
   --> result="省份|城市|运营商|区号|邮编|行政区划代码"
    */
}

普通版 每秒200w+

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

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/163148.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 「7年了!GTA 5联机版加载还是这么慢??一个if语句循环了19.8亿次??你的CPU在抽烟」

    「7年了!GTA 5联机版加载还是这么慢??一个if语句循环了19.8亿次??你的CPU在抽烟」你以为我上GitHub就是在学习?你以为我上GTA5就一定是在玩游戏?「7年了!GTA5联机版加载还是这么慢??」别急先献上地址https://github.com/tostercx/GTAO_Booster_PoC详情下面慢慢去了解只需要如下操作:gitclone—recurse-submoduleshttps://github.com/tostercx/GTAO_Booster_PoC之后,把dll文件粘贴到游戏根目录下就OK!彻底提升启动速度70%△Pleasewaitfor

    2022年4月30日
    208
  • Bluetooth flow control

    Bluetooth flow controlBaseband4.5.3FlowcontrolSincetheRXACLbuffercanbefullwhileanewpayloadarrives,flowcontrolisrequired.TheheaderfieldFLOWinthereturnTXpacketmayuseSTOPorGOinorderto…

    2022年6月5日
    27
  • java中array的方法_array java

    java中array的方法_array java题目要求为:卡拉兹(Callatz)猜想:对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去,最后一定在某一步得到n=1。当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对n=3进行验证的时候,我们需要计算3、5、8、4、2、1,则当我们对n=5、8、4、2进行验证的时候,就可以直接判定卡拉兹猜想的…

    2022年9月20日
    0
  • java如何完美的接参数JSONObject 转List集合[通俗易懂]

    一、描述日常中,前端传递一些json字符串等。。后端是如何去接受并处理呢?今天就用alibaba的fastjson简单描述下二、代码@PostMapping(“/getJson”)publicvoidgetJson(@RequestBodyJSONObjectjsonObject){ //获取到我们的jsonobject参数,并toJSONStringStrings=JSONArray.toJSONString(jsonObject.get(“An

    2022年4月9日
    419
  • 操作系统概念第七章部分作业题答案

    操作系统概念第七章部分作业题答案题目一:考虑下图所示的交通死锁的情况:(1)请说明这个实例中死锁的4个必要条件(2)请设计一条简单的规则来避免产生死锁解答:(1):死锁的四个必要条件是:①互斥:至少一个资源非共享,即一次只能有一个进程使用②占有并等待:一个进程至少占有一个资源,并等待另一个资源,而该资源被其他进程所占有③非抢占:资源非抢占,只有当前进程完成任务才能被释放④循环等待:有一组等待进城P0…P…

    2022年7月14日
    15
  • phpstorm2021.3激活码(在线激活)

    phpstorm2021.3激活码(在线激活),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月14日
    182

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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