ALI1416 / phone2region

Phone Number To Region 手机号码转区域

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Phone Number To Region 手机号码转区域

License Java Support Maven Central Tag Repo Size

Java CI Coverage Reliability Rating Maintainability Rating Security Rating

简介

本项目根据EeeMt/phone-number-geo重构,并加上了数据文件压缩后从外部导入、静态方法调用等,以及支持SpringBoot自动配置

数据文件

依赖导入

<dependency>
  <groupId>cn.404z</groupId>
  <artifactId>phone2region</artifactId>
  <version>2.2.0</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.4.11</version>
</dependency>

使用方法

定义常量

final String url = "https://www.404z.cn/files/phone2region/v2.0.0/data/phone2region.zdb";
final String zdbPath = "E:/phone2region.zdb";
final String txtPath = "E:/phone2region.txt";
final String errorPath = "E:/phone2region.error.txt";
final int phone = 1875471;

通过url初始化

log.info("是否已经初始化:{}", Phone2Region.initialized());
Phone2Region.initByUrl(url);
log.info(String.valueOf(Phone2Region.initialized()));
log.info("是否已经初始化:{}", Phone2Region.initialized());
log.info(String.valueOf(Phone2Region.parse(phone)));
// INFO cn.z.phone2region.Phone2RegionTest -- 是否已经初始化:false
// INFO cn.z.phone2region.Phone2Region -- 手机号码转区域初始化:URL路径URL_PATH https://www.404z.cn/files/phone2region/v2.0.0/data/phone2region.zdb
// INFO cn.z.phone2region.Phone2Region -- 数据加载成功:版本号VERSION 20230225 ,校验码CRC32 C8AEEA0A
// INFO cn.z.phone2region.Phone2RegionTest -- 是否已经初始化:true
// INFO cn.z.phone2region.Phone2RegionTest -- Region{province='山东', city='济宁', zipCode='272000', areaCode='0537', isp='移动'}

通过文件初始化

Phone2Region.initByFile(zdbPath);
log.info(String.valueOf(Phone2Region.parse(phone)));
// INFO cn.z.phone2region.Phone2Region -- 手机号码转区域初始化:文件路径LOCAL_PATH E:/phone2region.zdb
// INFO cn.z.phone2region.Phone2Region -- 数据加载成功:版本号VERSION 20230225 ,校验码CRC32 C8AEEA0A
// INFO cn.z.phone2region.Phone2RegionTest -- Region{province='山东', city='济宁', zipCode='272000', areaCode='0537', isp='移动'}

通过inputStream初始化

Phone2Region.init(new FileInputStream(zdbPath));
log.info(String.valueOf(Phone2Region.parse(phone)));
// INFO cn.z.phone2region.Phone2Region -- 数据加载成功:版本号VERSION 20230225 ,校验码CRC32 C8AEEA0A
// INFO cn.z.phone2region.Phone2RegionTest -- Region{province='山东', city='济宁', zipCode='272000', areaCode='0537', isp='移动'}

初始化多次

Phone2Region.initByFile(zdbPath);
Phone2Region.initByFile(zdbPath);
log.info(String.valueOf(Phone2Region.parse(phone)));
// INFO cn.z.phone2region.Phone2Region -- 手机号码转区域初始化:文件路径LOCAL_PATH E:/phone2region.zdb
// INFO cn.z.phone2region.Phone2Region -- 数据加载成功:版本号VERSION 20230225 ,校验码CRC32 C8AEEA0A
// WARN cn.z.phone2region.Phone2Region -- 已经初始化过了,不可重复初始化!
// INFO cn.z.phone2region.Phone2RegionTest -- Region{province='山东', city='济宁', zipCode='272000', areaCode='0537', isp='移动'}

初始化异常

try {
    Phone2Region.initByFile("A:/1.txt");
} catch (Exception e) {
    e.printStackTrace();
}
log.info(String.valueOf(Phone2Region.parse(phone)));
// INFO cn.z.phone2region.Phone2Region -- 手机号码转区域初始化:文件路径LOCAL_PATH A:/1.txt
// ERROR cn.z.phone2region.Phone2Region -- 初始化文件异常!
// java.io.FileNotFoundException: A:\1.txt (系统找不到指定的路径。)
// cn.z.phone2region.Phone2RegionException: 初始化文件异常!
// cn.z.phone2region.Phone2RegionException: 未初始化!

数据错误

Phone2Region.initByFile(zdbPath);
try {
    Phone2Region.parse("123456789012");
} catch (Exception e) {
    e.printStackTrace();
}
try {
    Phone2Region.parse(-1L);
} catch (Exception e) {
    e.printStackTrace();
}
// INFO cn.z.phone2region.Phone2Region -- 手机号码转区域初始化:文件路径LOCAL_PATH E:/phone2region.zdb
// INFO cn.z.phone2region.Phone2Region -- 数据加载成功:版本号VERSION 20230225 ,校验码CRC32 C8AEEA0A
// cn.z.phone2region.Phone2RegionException: 手机号码 123456789012 不合法!
// cn.z.phone2region.Phone2RegionException: 手机号码 -1 不合法!

性能测试

Phone2Region.initByFile(zdbPath);
log.info(String.valueOf(Phone2Region.parse(phone)));
long startTime = System.currentTimeMillis();
for (int i = 1300000; i < 2000000; i++) {
    Phone2Region.parse(i);
}
long endTime = System.currentTimeMillis();
log.info("查询 {} 条数据,用时 {} 毫秒", 700000, endTime - startTime);
// INFO cn.z.phone2region.Phone2Region -- 手机号码转区域初始化:文件路径LOCAL_PATH E:/phone2region.zdb
// INFO cn.z.phone2region.Phone2Region -- 数据加载成功:版本号VERSION 20230225 ,校验码CRC32 C8AEEA0A
// INFO cn.z.phone2region.Phone2RegionTest -- Region{province='山东', city='济宁', zipCode='272000', areaCode='0537', isp='移动'}
// INFO cn.z.phone2region.Phone2RegionTest - 查询 700000 条数据,用时 173 毫秒

完整性测试

Phone2Region.initByFile(zdbPath);
log.info(String.valueOf(Phone2Region.parse(phone)));
long startTime = System.currentTimeMillis();
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(errorPath));
BufferedReader bufferedReader = new BufferedReader(new FileReader(txtPath));
String line = bufferedReader.readLine();
int successCount = 0;
int errorCount = 0;
int nextPhone = 1300000;
int nullCount = 0;
while (line != null && !line.isEmpty()) {
    // 手机号码前7位|省份|城市|邮编|区号|ISP
    String[] s = line.split("\\|");
    String record = s[1] + "|" // 省份
            + s[2] + "|" // 城市
            + s[3] + "|" // 邮编
            + s[4] + "|" // 区号
            + s[5]; // ISP
    int phone = Integer.parseInt(s[0]);
    if (phone != nextPhone) {
        int count = phone - nextPhone;
        for (int i = 0; i < count; i++) {
            if (Phone2Region.parse(nextPhone + i) != null) {
                String error = "手机号码`" + (nextPhone + i) + "`解析错误,实际为`null`";
                errorCount++;
                log.error(error);
                bufferedWriter.write(error + "\n");
            }
        }
        nullCount += count;
        nextPhone += count;
    }
    int hash = (new Region(record)).toString().hashCode();
    if (hash != Phone2Region.parse(phone).toString().hashCode()) {
        String error = "解析记录`" + line + "`时发现手机号码`" + phone //
                + "`解析错误,实际为`" + Phone2Region.parse(phone) + "`";
        errorCount++;
        log.error(error);
        bufferedWriter.write(error + "\n");
    }
    successCount++;
    nextPhone++;
    line = bufferedReader.readLine();
}
for (int i = nextPhone; i < 2000000; i++) {
    if (Phone2Region.parse(i) != null) {
        String error = "手机号码`" + (i) + "`解析错误,实际为`null`";
        errorCount++;
        log.error(error);
        bufferedWriter.write(error + "\n");
    }
}
nullCount += (2000000 - nextPhone);
bufferedReader.close();
bufferedWriter.flush();
bufferedWriter.close();
long endTime = System.currentTimeMillis();
log.info("解析 {} 条数据,有值 {} 条,空值 {} 条,错误 {} 条,用时 {} 毫秒", 700000, successCount, nullCount, errorCount,
        endTime - startTime);
// INFO cn.z.phone2region.Phone2Region -- 手机号码转区域初始化:文件路径LOCAL_PATH E:/phone2region.zdb
// INFO cn.z.phone2region.Phone2Region -- 数据加载成功:版本号VERSION 20230225 ,校验码CRC32 C8AEEA0A
// INFO cn.z.phone2region.Phone2RegionTest -- Region{province='山东', city='济宁', zipCode='272000', areaCode='0537', isp='移动'}
// INFO cn.z.phone2region.Phone2RegionTest - 解析 700000 条数据,有值 497191 条,空值 202809 条,错误 0 条,用时 783 毫秒

更多请见测试

更新日志

点击查看

关于

About

About

Phone Number To Region 手机号码转区域

License:Apache License 2.0


Languages

Language:Java 100.0%