Appearance
号段查询(使用qqzeng)
v3版本
集成工具类示例:
go
package qqzengphone
/**
@author: liqiang@konyun.net
参考原作者代码整理,已测试
**/
import (
"callcenter_backend/pkg/logger"
"encoding/binary"
"fmt"
"os"
"strconv"
"strings"
)
type QqzengPhoneV3 struct {
data []byte
phone2D [][]int
addrArr []string
ispArr []string
}
func NewQqzengPhoneV3(filepath string) (*QqzengPhoneV3, error) {
data, err := os.ReadFile(filepath)
if err != nil {
logger.Errorf("Error reading the dat file:%v", err)
return nil, err
}
PrefSize := binary.LittleEndian.Uint32(data[0:4])
descLength := binary.LittleEndian.Uint32(data[8:12])
ispLength := binary.LittleEndian.Uint32(data[12:16])
headLength := 20
startIndex := headLength + int(descLength) + int(ispLength)
// Description array
descString := string(data[headLength : headLength+int(descLength)])
addrArr := strings.Split(descString, "&")
// ISP array
ispString := string(data[headLength+int(descLength) : headLength+int(descLength)+int(ispLength)])
ispArr := strings.Split(ispString, "&")
// Phone2D array
phone2D := make([][]int, 200)
for m := 0; m < int(PrefSize); m++ {
i := m*7 + startIndex
pref := int(data[i])
index := int(binary.LittleEndian.Uint32(data[i+1 : i+5]))
length := int(binary.LittleEndian.Uint16(data[i+5 : i+7]))
phone2D[pref] = make([]int, 10000)
for n := 0; n < length; n++ {
p := startIndex + int(PrefSize)*7 + (n+index)*4
suff := int(binary.LittleEndian.Uint16(data[p : p+2]))
addrispIndex := int(binary.LittleEndian.Uint16(data[p+2 : p+4]))
phone2D[pref][suff] = addrispIndex
}
}
return &QqzengPhoneV3{
data: data,
phone2D: phone2D,
addrArr: addrArr,
ispArr: ispArr,
}, nil
}
func (psb *QqzengPhoneV3) Get(phone string) string {
prefix := phone[:3]
suffix := phone[3:7]
pref, _ := strconv.Atoi(prefix)
suff, _ := strconv.Atoi(suffix)
addrispIndex := psb.phone2D[pref][suff]
if addrispIndex == 0 {
return ""
}
addr := psb.addrArr[addrispIndex/100]
isp := psb.ispArr[addrispIndex%100]
return fmt.Sprintf("%s|%s", addr, isp)
}调用示例:
go
package qqzengphone
/**
@author: liqiang@konyun.net
**/
import (
"fmt"
"testing"
)
func TestQqzengv3(t *testing.T) {
filePath := "/Users/van/go_workspace/callcenter/callcenter_backend/uploads/qqzeng-phone-3.0.dat"
finder, err := NewQqzengPhoneV3(filePath)
if err != nil {
fmt.Println("Error:", err)
return
}
phone := "13872295563"
result := finder.Get(phone)
fmt.Println(phone)
fmt.Println(result)
}v5版本
集成工具类示例:
go
package qqzengphone
/**
@author: liqiang@konyun.net
参考原作者java代码整理,已测试
**/
import (
"callcenter_backend/pkg/logger"
"encoding/binary"
"fmt"
"os"
"strconv"
"strings"
)
type QqzengPhoneV5 struct {
prefmap [200][2]uint32
phonemap [][2]uint32
phoneArr []uint32
addrArr []string
ispArr []string
}
func NewQqzengPhoneV5(path string) (*QqzengPhoneV5, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var prefSize, recordSize, descLength, ispLength uint32
prefSize = binary.LittleEndian.Uint32(data[:4])
recordSize = binary.LittleEndian.Uint32(data[4:8])
descLength = binary.LittleEndian.Uint32(data[8:12])
ispLength = binary.LittleEndian.Uint32(data[12:16])
descOffset := int(16 + prefSize*9 + recordSize*7)
descString := string(data[descOffset : descOffset+int(descLength)])
addrArr := strings.Split(descString, "&")
ispOffset := descOffset + int(descLength)
ispString := string(data[ispOffset : ispOffset+int(ispLength)])
ispArr := strings.Split(ispString, "&")
var prefmap [200][2]uint32
for k := 0; k < int(prefSize); k++ {
i := k*9 + 16
n := uint32(data[i]) & 0xFF
prefmap[n][0] = binary.LittleEndian.Uint32(data[i+1 : i+5])
prefmap[n][1] = binary.LittleEndian.Uint32(data[i+5 : i+9])
}
phoneArr := make([]uint32, int(recordSize))
phonemap := make([][2]uint32, int(recordSize))
for i := 0; i < int(recordSize); i++ {
p := 16 + int(prefSize)*9 + i*7
phoneArr[i] = BytesToLong(data[p], data[1+p], data[2+p], data[3+p])
phonemap[i][0] = BytesToLong(data[4+p], data[5+p], byte(0), byte(0))
phonemap[i][1] = BytesToLong(data[6+p], byte(0), byte(0), byte(0))
}
return &QqzengPhoneV5{
prefmap: prefmap,
phonemap: phonemap,
phoneArr: phoneArr,
addrArr: addrArr,
ispArr: ispArr,
}, nil
}
func BytesToLong(a, b, c, d byte) uint32 {
var bytes [4]byte
bytes[0] = a
bytes[1] = b
bytes[2] = c
bytes[3] = d
var num uint32
binary.BigEndian.PutUint32(bytes[:], uint32(a)|(uint32(b)<<8)|(uint32(c)<<16)|(uint32(d)<<24))
num = uint32(binary.BigEndian.Uint32(bytes[:]))
return num
}
func (p *QqzengPhoneV5) Get(phone string) string {
prefStr := phone[:3]
valStr := phone[:7]
pref, err := strconv.Atoi(prefStr)
if err != nil {
logger.Errorf("err:%v", err)
}
val, err := strconv.Atoi(valStr)
if err != nil {
logger.Errorf("err:%v", err)
}
low := int(p.prefmap[pref][0])
high := int(p.prefmap[pref][1])
if high == 0 {
return ""
}
cur := p.binarySearch(low, high, uint32(val))
if cur != -1 {
return fmt.Sprintf("%s|%s", p.addrArr[p.phonemap[cur][0]], p.ispArr[p.phonemap[cur][1]])
}
return ""
}
func (p *QqzengPhoneV5) binarySearch(low, high int, k uint32) int {
M := 0
for low <= high {
mid := (low + high) / 2
phoneNumber := p.phoneArr[mid]
if phoneNumber >= k {
M = mid
if mid == 0 {
break
}
high = mid - 1
} else {
low = mid + 1
}
}
return M
}调用示例:
go
package qqzengphone
/**
@author: liqiang@konyun.net
**/
import (
"fmt"
"testing"
)
func TestQqzengv5(t *testing.T) {
filePath := "/Users/van/go_workspace/callcenter/callcenter_backend/uploads/qqzeng-phone-5.0.dat"
finder, err := NewQqzengPhoneV5(filePath)
if err != nil {
fmt.Println("Error:", err)
return
}
phone := "13872295563"
result := finder.Get(phone)
fmt.Println(phone)
fmt.Println(result)
}