mirror of
https://github.com/zu1k/nali.git
synced 2025-01-22 13:19:02 +08:00
mod
This commit is contained in:
parent
dc365d3359
commit
8068e43037
@ -21,7 +21,7 @@ var updateCmd = &cobra.Command{
|
||||
filePath := filepath.Join(constant.HomePath, "qqwry.dat")
|
||||
|
||||
log.Println("正在下载最新纯真 IP 库...")
|
||||
tmpData, err := qqwry.GetOnline()
|
||||
tmpData, err := qqwry.Download()
|
||||
if err != nil {
|
||||
log.Fatalln("下载失败", err.Error())
|
||||
return
|
||||
|
@ -1,6 +1,8 @@
|
||||
package common
|
||||
|
||||
const (
|
||||
RedirectMode1 = 0x01 // one mode
|
||||
RedirectMode2 = 0x02 //another mode
|
||||
// RedirectMode1 [IP][0x01][国家和地区信息的绝对偏移地址]
|
||||
RedirectMode1 = 0x01
|
||||
// RedirectMode2 [IP][0x02][信息的绝对偏移][...] or [IP][国家][...]
|
||||
RedirectMode2 = 0x02
|
||||
)
|
||||
|
@ -1,6 +1,5 @@
|
||||
package common
|
||||
|
||||
// byteToUInt32 将 byte 转换为uint32
|
||||
func ByteToUInt32(data []byte) uint32 {
|
||||
i := uint32(data[0]) & 0xff
|
||||
i |= (uint32(data[1]) << 8) & 0xff00
|
||||
|
@ -19,19 +19,19 @@ type QQwry struct {
|
||||
|
||||
// NewQQwry new db from path
|
||||
func NewQQwry(filePath string) QQwry {
|
||||
var tmpData []byte
|
||||
var fileData []byte
|
||||
var fileInfo common.FileInfo
|
||||
|
||||
// 判断文件是否存在
|
||||
_, err := os.Stat(filePath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
log.Println("文件不存在,尝试从网络获取最新纯真 IP 库")
|
||||
tmpData, err = GetOnline()
|
||||
fileData, err = Download()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
if err := ioutil.WriteFile(filePath, tmpData, 0644); err == nil {
|
||||
log.Printf("已将最新的纯真 IP 库保存到本地 %s ", filePath)
|
||||
if err := ioutil.WriteFile(filePath, fileData, 0644); err == nil {
|
||||
log.Printf("已将最新的 纯真IP库 保存到本地: %s ", filePath)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -42,13 +42,12 @@ func NewQQwry(filePath string) QQwry {
|
||||
}
|
||||
defer fileInfo.FileBase.Close()
|
||||
|
||||
tmpData, err = ioutil.ReadAll(fileInfo.FileBase)
|
||||
fileData, err = ioutil.ReadAll(fileInfo.FileBase)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
fileInfo.Data = tmpData
|
||||
fileInfo.Data = fileData
|
||||
|
||||
buf := fileInfo.Data[0:8]
|
||||
start := binary.LittleEndian.Uint32(buf[:4])
|
||||
@ -64,14 +63,14 @@ func NewQQwry(filePath string) QQwry {
|
||||
}
|
||||
|
||||
// Find ip地址查询对应归属地信息
|
||||
func (q QQwry) Find(ip string) (res string) {
|
||||
func (db QQwry) Find(ip string) (res string) {
|
||||
if strings.Count(ip, ".") != 3 {
|
||||
return
|
||||
}
|
||||
|
||||
ip4 := binary.BigEndian.Uint32(net.ParseIP(ip).To4())
|
||||
|
||||
offset := q.searchIndex(ip4)
|
||||
offset := db.searchIndex(ip4)
|
||||
if offset <= 0 {
|
||||
return
|
||||
}
|
||||
@ -79,27 +78,27 @@ func (q QQwry) Find(ip string) (res string) {
|
||||
var gbkCountry []byte
|
||||
var gbkArea []byte
|
||||
|
||||
mode := q.ReadMode(offset + 4)
|
||||
mode := db.ReadMode(offset + 4)
|
||||
// [IP][0x01][国家和地区信息的绝对偏移地址]
|
||||
if mode == common.RedirectMode1 {
|
||||
countryOffset := q.ReadUInt24()
|
||||
mode = q.ReadMode(countryOffset)
|
||||
countryOffset := db.ReadUInt24()
|
||||
mode = db.ReadMode(countryOffset)
|
||||
if mode == common.RedirectMode2 {
|
||||
c := q.ReadUInt24()
|
||||
gbkCountry = q.ReadString(c)
|
||||
c := db.ReadUInt24()
|
||||
gbkCountry = db.ReadString(c)
|
||||
countryOffset += 4
|
||||
} else {
|
||||
gbkCountry = q.ReadString(countryOffset)
|
||||
gbkCountry = db.ReadString(countryOffset)
|
||||
countryOffset += uint32(len(gbkCountry) + 1)
|
||||
}
|
||||
gbkArea = q.ReadArea(countryOffset)
|
||||
gbkArea = db.ReadArea(countryOffset)
|
||||
} else if mode == common.RedirectMode2 {
|
||||
countryOffset := q.ReadUInt24()
|
||||
gbkCountry = q.ReadString(countryOffset)
|
||||
gbkArea = q.ReadArea(offset + 8)
|
||||
countryOffset := db.ReadUInt24()
|
||||
gbkCountry = db.ReadString(countryOffset)
|
||||
gbkArea = db.ReadArea(offset + 8)
|
||||
} else {
|
||||
gbkCountry = q.ReadString(offset + 4)
|
||||
gbkArea = q.ReadArea(offset + uint32(5+len(gbkCountry)))
|
||||
gbkCountry = db.ReadString(offset + 4)
|
||||
gbkArea = db.ReadArea(offset + uint32(5+len(gbkCountry)))
|
||||
}
|
||||
|
||||
enc := simplifiedchinese.GBK.NewDecoder()
|
||||
@ -110,24 +109,24 @@ func (q QQwry) Find(ip string) (res string) {
|
||||
}
|
||||
|
||||
// searchIndex 查找索引位置
|
||||
func (q *QQwry) searchIndex(ip uint32) uint32 {
|
||||
header := q.ReadData(8, 0)
|
||||
func (db *QQwry) searchIndex(ip uint32) uint32 {
|
||||
header := db.ReadData(8, 0)
|
||||
|
||||
start := binary.LittleEndian.Uint32(header[:4])
|
||||
end := binary.LittleEndian.Uint32(header[4:])
|
||||
|
||||
buf := make([]byte, q.IndexLen)
|
||||
buf := make([]byte, db.IndexLen)
|
||||
mid := uint32(0)
|
||||
_ip := uint32(0)
|
||||
|
||||
for {
|
||||
mid = q.GetMiddleOffset(start, end)
|
||||
buf = q.ReadData(q.IndexLen, mid)
|
||||
mid = db.GetMiddleOffset(start, end)
|
||||
buf = db.ReadData(db.IndexLen, mid)
|
||||
_ip = binary.LittleEndian.Uint32(buf[:4])
|
||||
|
||||
if end-start == q.IndexLen {
|
||||
if end-start == db.IndexLen {
|
||||
offset := common.ByteToUInt32(buf[4:])
|
||||
buf = q.ReadData(q.IndexLen)
|
||||
buf = db.ReadData(db.IndexLen)
|
||||
if ip < binary.LittleEndian.Uint32(buf[:4]) {
|
||||
return offset
|
||||
}
|
||||
|
@ -8,7 +8,43 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func getKey() (uint32, error) {
|
||||
func Download() (data []byte, err error) {
|
||||
resp, err := http.Get("https://qqwry.mirror.noc.one/qqwry.rar")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key, err := getCopyWriteKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return unRar(body, key)
|
||||
}
|
||||
|
||||
func unRar(data []byte, key uint32) ([]byte, error) {
|
||||
for i := 0; i < 0x200; i++ {
|
||||
key = key * 0x805
|
||||
key++
|
||||
key = key & 0xff
|
||||
|
||||
data[i] = byte(uint32(data[i]) ^ key)
|
||||
}
|
||||
|
||||
reader, err := zlib.NewReader(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ioutil.ReadAll(reader)
|
||||
}
|
||||
|
||||
func getCopyWriteKey() (uint32, error) {
|
||||
resp, err := http.Get("https://qqwry.mirror.noc.one/copywrite.rar")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -21,35 +57,3 @@ func getKey() (uint32, error) {
|
||||
return binary.LittleEndian.Uint32(body[5*4:]), nil
|
||||
}
|
||||
}
|
||||
|
||||
// get db content from mirror
|
||||
func GetOnline() ([]byte, error) {
|
||||
resp, err := http.Get("https://qqwry.mirror.noc.one/qqwry.rar")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if body, err := ioutil.ReadAll(resp.Body); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
if key, err := getKey(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
for i := 0; i < 0x200; i++ {
|
||||
key = key * 0x805
|
||||
key++
|
||||
key = key & 0xff
|
||||
|
||||
body[i] = byte(uint32(body[i]) ^ key)
|
||||
}
|
||||
|
||||
reader, err := zlib.NewReader(bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ioutil.ReadAll(reader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ func NewZXwry(filePath string) ZXwry {
|
||||
}
|
||||
}
|
||||
|
||||
func (q ZXwry) Find(ip string) (result string) {
|
||||
q.Offset = 0
|
||||
func (db ZXwry) Find(ip string) (result string) {
|
||||
db.Offset = 0
|
||||
|
||||
tp := big.NewInt(0)
|
||||
op := big.NewInt(0)
|
||||
@ -60,58 +60,50 @@ func (q ZXwry) Find(ip string) (result string) {
|
||||
tp.SetString("FFFFFFFFFFFFFFFF", 16)
|
||||
op.And(op, tp)
|
||||
|
||||
v6ip := op.Uint64()
|
||||
offset := q.searchIndex(v6ip)
|
||||
|
||||
country, area := q.getAddr(offset)
|
||||
|
||||
if area == "ZX" {
|
||||
area = ""
|
||||
}
|
||||
|
||||
ipv6 := op.Uint64()
|
||||
offset := db.searchIndex(ipv6)
|
||||
country, area := db.getAddr(offset)
|
||||
return fmt.Sprintf("%s %s", country, area)
|
||||
}
|
||||
|
||||
func (q *ZXwry) getAddr(offset uint32) (string, string) {
|
||||
mode := q.ReadMode(offset)
|
||||
func (db *ZXwry) getAddr(offset uint32) (string, string) {
|
||||
mode := db.ReadMode(offset)
|
||||
if mode == common.RedirectMode1 {
|
||||
// [IP][0x01][国家和地区信息的绝对偏移地址]
|
||||
offset = q.ReadUInt24()
|
||||
return q.getAddr(offset)
|
||||
offset = db.ReadUInt24()
|
||||
return db.getAddr(offset)
|
||||
}
|
||||
// [IP][0x02][信息的绝对偏移][...] or [IP][国家][...]
|
||||
_offset := q.Offset - 1
|
||||
c1 := q.ReadArea(_offset)
|
||||
_offset := db.Offset - 1
|
||||
c1 := db.ReadArea(_offset)
|
||||
if mode == common.RedirectMode2 {
|
||||
q.Offset = 4 + _offset
|
||||
db.Offset = 4 + _offset
|
||||
} else {
|
||||
q.Offset = _offset + uint32(1+len(c1))
|
||||
db.Offset = _offset + uint32(1+len(c1))
|
||||
}
|
||||
c2 := q.ReadArea(q.Offset)
|
||||
c2 := db.ReadArea(db.Offset)
|
||||
return string(c1), string(c2)
|
||||
}
|
||||
|
||||
func (q *ZXwry) searchIndex(ip uint64) uint32 {
|
||||
q.ItemLen = 8
|
||||
q.IndexLen = 11
|
||||
func (db *ZXwry) searchIndex(ip uint64) uint32 {
|
||||
db.ItemLen = 8
|
||||
db.IndexLen = 11
|
||||
|
||||
header := q.Data.Data[8:24]
|
||||
header := db.Data.Data[8:24]
|
||||
start := binary.LittleEndian.Uint32(header[8:])
|
||||
counts := binary.LittleEndian.Uint32(header[:8])
|
||||
end := start + counts*q.IndexLen
|
||||
end := start + counts*db.IndexLen
|
||||
|
||||
buf := make([]byte, q.IndexLen)
|
||||
buf := make([]byte, db.IndexLen)
|
||||
|
||||
for {
|
||||
mid := q.GetMiddleOffset(start, end)
|
||||
buf = q.Data.Data[mid : mid+q.IndexLen]
|
||||
_ip := binary.LittleEndian.Uint64(buf[:q.ItemLen])
|
||||
mid := db.GetMiddleOffset(start, end)
|
||||
buf = db.Data.Data[mid : mid+db.IndexLen]
|
||||
_ip := binary.LittleEndian.Uint64(buf[:db.ItemLen])
|
||||
|
||||
if end-start == q.IndexLen {
|
||||
if ip >= binary.LittleEndian.Uint64(q.Data.Data[end:end+q.ItemLen]) {
|
||||
buf = q.Data.Data[end : end+q.IndexLen]
|
||||
if end-start == db.IndexLen {
|
||||
if ip >= binary.LittleEndian.Uint64(db.Data.Data[end:end+db.ItemLen]) {
|
||||
buf = db.Data.Data[end : end+db.IndexLen]
|
||||
}
|
||||
return common.ByteToUInt32(buf[q.ItemLen:])
|
||||
return common.ByteToUInt32(buf[db.ItemLen:])
|
||||
}
|
||||
|
||||
if _ip > ip {
|
||||
@ -119,7 +111,7 @@ func (q *ZXwry) searchIndex(ip uint64) uint32 {
|
||||
} else if _ip < ip {
|
||||
start = mid
|
||||
} else if _ip == ip {
|
||||
return common.ByteToUInt32(buf[q.ItemLen:])
|
||||
return common.ByteToUInt32(buf[db.ItemLen:])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user