java學習筆記(三)手機歸屬地查詢的程式碼,親測可用
阿新 • • 發佈:2018-12-15
由於公司行業主要是展會行業,展會上的觀眾註冊等,填寫基本資訊的時候會採集手機號等資訊,展會結束後我們需要做資料分析。只有通過手機號查詢歸屬地來獲取客戶的地域資訊。找了好多平臺和api,發現沒有說是能批量處理手機號資訊。最後還是找了githup上找到一個外掛,感謝那位大神的貢獻。
傳送門> https://github.com/xluohome/phonedata 主要涉及到兩個類和一個dat檔案 PhoneNumberGeo.java 和 PhoneNumberInfo.java 以及一個 phone.dat檔案(存放手機歸屬資訊的),dat檔案可在傳送門裡面找到。 PhoneNumberGeo.java 檔案內容如下,主要作用是來讀取phone.dat檔案。
package com.yh.util.phone; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.Scanner; /** * Created by buring 18/10/12. */ public class PhoneNumberGeo { private static String[] numberType = {null, "移動", "聯通", "電信", "電信虛擬運營商", "聯通虛擬運營商", "移動虛擬運營商"}; private static final int INDEX_SEGMENT_LENGTH = 9; private static byte[] dataByteArray; private ByteBuffer byteBuffer; private int indexAreaOffset = -1; private int phoneRecordCount = -1; public PhoneNumberGeo() { if (dataByteArray == null) { synchronized (PhoneNumberGeo.class) { if (dataByteArray == null) { ByteArrayOutputStream byteData = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int readBytesLength; try { InputStream inputStream = PhoneNumberGeo.class .getResourceAsStream("phone.dat"); while ((readBytesLength = inputStream.read(buffer)) != -1) { byteData.write(buffer, 0, readBytesLength); } inputStream.close(); } catch (Exception e) { System.err.println("Can't find phone.dat in classpath:phone-number-geo/phone.dat"); e.printStackTrace(); throw new RuntimeException(e); } dataByteArray = byteData.toByteArray(); } } } byteBuffer = ByteBuffer.wrap(dataByteArray); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); int dataVersion = byteBuffer.getInt(); indexAreaOffset = byteBuffer.getInt(); // print data version // System.out.println(dataVersion); phoneRecordCount = (dataByteArray.length - indexAreaOffset) / INDEX_SEGMENT_LENGTH; // print record count // System.out.println(phoneRecordCount); } public PhoneNumberInfo lookup(String phoneNumber) { if (phoneNumber == null || phoneNumber.length() > 11 || phoneNumber.length() < 7) { return null; } int phoneNumberPrefix; try { phoneNumberPrefix = Integer.parseInt(phoneNumber.substring(0, 7)); } catch (Exception e) { return null; } int left = 0; int right = phoneRecordCount; while (left <= right) { int middle = (left + right) >> 1; int currentOffset = indexAreaOffset + middle * INDEX_SEGMENT_LENGTH; if (currentOffset >= dataByteArray.length) { return null; } byteBuffer.position(currentOffset); int currentPrefix = byteBuffer.getInt(); if (currentPrefix > phoneNumberPrefix) { right = middle - 1; } else if (currentPrefix < phoneNumberPrefix) { left = middle + 1; } else { int infoBeginOffset = byteBuffer.getInt(); int phoneType = byteBuffer.get(); int infoLength = -1; for (int i = infoBeginOffset; i < indexAreaOffset; ++i) { if (dataByteArray[i] == 0) { infoLength = i - infoBeginOffset; break; } } String infoString = new String(dataByteArray, infoBeginOffset, infoLength, StandardCharsets.UTF_8); String[] infoSegments = infoString.split("\\|"); PhoneNumberInfo phoneNumberInfo = new PhoneNumberInfo(); phoneNumberInfo.setPhoneNumber(phoneNumber); phoneNumberInfo.setProvince(infoSegments[0]); phoneNumberInfo.setCity(infoSegments[1]); phoneNumberInfo.setZipCode(infoSegments[2]); phoneNumberInfo.setAreaCode(infoSegments[3]); phoneNumberInfo.setPhoneType(numberType[phoneType]); return phoneNumberInfo; } } return null; } public static void main(String[] args) { PhoneNumberGeo phoneNumberGeo = new PhoneNumberGeo(); Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { System.out.println(phoneNumberGeo.lookup(scanner.next())); } } }
PhoneNumberInfo.java 檔案內容如下,主要作用 定義一個model
package com.yh.util.phone; public class PhoneNumberInfo { private String phoneNumber; private String province; private String city; private String zipCode; private String areaCode; private String phoneType; public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } public String getAreaCode() { return areaCode; } public void setAreaCode(String areaCode) { this.areaCode = areaCode; } public String getPhoneType() { return phoneType; } public void setPhoneType(String phoneType) { this.phoneType = phoneType; } @Override public String toString() { return "PhoneNumberInfo{" + "phoneNumber='" + phoneNumber + '\'' + ", province='" + province + '\'' + ", city='" + city + '\'' + ", zipCode='" + zipCode + '\'' + ", areaCode='" + areaCode + '\'' + ", phoneType='" + phoneType + '\'' + '}'; } }
檔案存放路徑建議 呼叫的程式碼如下
String phoneNum = '13609257706'
PhoneNumberGeo phoneNumberGeo = new PhoneNumberGeo();
PhoneNumberInfo phoneNumberInfo = phoneNumberGeo.lookup(val);
if(null!=phoneNumberInfo){
//獲取省份
String province = phoneNumberInfo.getProvince();
//獲取城市 需要其他的引數自行查詢PhoneNumberInfo類獲取
String city = phoneNumberInfo.getCity();
System.out.println(province+"\t"+city);
}else{
System.out.println("請單獨去查詢");
}
有問題請隨時@,郵箱[email protected]