最新手机号段归属地数据库 (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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 职称计算机考试模块教程怎么用,如何巧妙的选择职称计算机考试模块?

    职称计算机考试模块教程怎么用,如何巧妙的选择职称计算机考试模块?【摘要】环球网校分享的如何巧妙的选择职称计算机考试模块?希望对大家备考有帮助,更多资料敬请关注环球职称计算机考试频道,网校会及时更新考试资料…… 相关推荐:全国2016年职称计算机考试报名时间汇总【摘要】环球网校分享的“如何巧妙的选择职称计算机考试模块?”希望对大家备考有帮助,更多资料敬请关注环球职称计算机考试频道,网校会及时更新考试资料……职称计算机考试,根据学习内容划分了十四类共25个模块,评…

    2022年6月2日
    36
  • bat批处理命令大全_文件批处理命令

    bat批处理命令大全_文件批处理命令批处理文件(batchfile)包含一系列DOS命令,通常用于自动执行重复性任务。用户只需双击批处理文件便可执行任务,而无需重复输入相同指令。编写批处理文件非常简单,但难点在于确保一切按顺序执行。编写严谨的批处理文件可以极大程度地节省时间,在应对重复性工作时尤其有效在Windows中善用批处理可以简化很多重复工作批处理? 批处理(Batch),也称为批处理脚本。顾名思义,批处理就是对某对象进行批量的处理。批处理文件的扩展名为bat 目前比较常见的批处理包含两类: DOS批

    2022年8月22日
    7
  • TINYTEXT,TEXT,MEDIUMTEXT和LONGTEXT最大存储容量

    TINYTEXT,TEXT,MEDIUMTEXT和LONGTEXT最大存储容量PertheMySQLdocs,therearefourTEXTtypes:根据MySQL文档,有四种TEXT类型:TINYTEXTTINYTEXTTEXT

    2022年8月13日
    5
  • bs架构和cs架构的比对方法_cs架构嵌入BS

    bs架构和cs架构的比对方法_cs架构嵌入BS1、CS、BS架构定义  CS(Client/Server):客户端—-服务器结构。C/S结构在技术上很成熟,它的主要特点是交互性强、具有安全的存取模式、网络通信量低、响应速度快、利于处理大量数据。因为客户端要负责绝大多数的业务逻辑和UI展示,又称为胖客户端。它充分利用两端硬件,将任务分配到Client和Server两端,降低了系统的通讯开销。C/S结构的软件需要针对不同

    2022年10月16日
    5
  • 电脑主板插线方法图解_JFP1主板插线图解

    电脑主板插线方法图解_JFP1主板插线图解

    2021年11月17日
    206
  • 支撑微博千亿调用的轻量级RPC框架:Motan「建议收藏」

    支撑微博千亿调用的轻量级RPC框架:Motan

    2022年3月12日
    49

发表回复

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

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