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

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

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

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

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

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

权威 全面 准确 规范

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

更新历史:

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条记录
…………

 

移动号段:
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

字段样例

//名称:手机号码归属地查询 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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
最新全国手机号归属地信息SQLite数据库是一个用于存储和查询手机归属地信息的数据库。该数据库包含了所有最新的全国手机号码与其对应的归属地信息,可以提供准确的归属地查询服务。 该数据库的构建过程可以分为以下几个步骤: 首先,需要收集全国手机号码与其对应的归属地信息。这个过程可以通过爬取网络上的手机归属地查询网站或者购买第三方提供的手机号归属数据库来获取。收集得到的数据应该包括手机号码和对应的归属地信息,例如省份和城市等。 接下来,需要创建一个SQLite数据库,并定义表结构,以存储手机号码和对应的归属地信息。表结构可以包括手机号码和归属地信息的字,以及索引提高查询效率。 然后,将收集到的手机号码和归属地信息导入到SQLite数据库中。可以使用SQLite的命令工具或者编写脚本来实现数据的导入。导入数据的过程需要按照表结构将数据插入到相应的字中。 最后,通过使用SQLite数据库提供的查询功能,可以根据用户提供的手机号码进归属地查询。用户可以通过查询手机号码在数据库中对应的记录,从而获取手机号码的归属地信息。 总结来说,最新全国手机号归属地信息SQLite数据库是一个用于存储和查询手机号归属地信息的数据库,通过收集手机号码和归属地信息,并导入到SQLite数据库中,可以提供准确的归属地查询服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值