ipip-datx
Version:
IPIP.net官方支持的IP数据库datx格式查询代码
92 lines (78 loc) • 2.44 kB
JavaScript
const fs = require('fs');
const net = require('net');
module.exports = class City {
constructor(name){
this.data = fs.readFileSync(name)
this.indexSize = this.bytes2Uint32(
this.data[0],
this.data[1],
this.data[2],
this.data[3]
);
}
findSync(ip){
if (!net.isIPv4(ip)){
return false;
}
let ips = ip.split(".")
let val = this.bytes2Uint32(ips[0], ips[1], ips[2], ips[3])
let low = 0;
let mid = 0;
let pos = 0;
let high = parseInt((this.indexSize - 262148 - 262144) / 9) - 1;
let pos1 = 0;
let start = 0;
let end = 0;
while (low <= high) {
mid = Math.ceil((low + high) / 2);
pos = mid * 9 + 262148;
start = 0;
if (mid > 0) {
pos1 = (mid - 1) * 9 + 262148;
start = this.bytes2Uint32(
this.data[pos1],
this.data[pos1 + 1],
this.data[pos1 + 2],
this.data[pos1 + 3]
) + 1;
}
end = this.bytes2Uint32(
this.data[pos],
this.data[pos + 1],
this.data[pos + 2],
this.data[pos + 3]
);
if (val < start) {
high = mid - 1;
} else if (val > end) {
low = mid + 1;
} else {
let off = this.bytes2Uint32(
0,
this.data[pos + 6],
this.data[pos + 5],
this.data[pos + 4]
);
let len = this.bytes2Uint32(
0,
0,
this.data[pos + 7],
this.data[pos + 8]
);
pos = off - 262144 + this.indexSize;
let buf = Buffer.alloc(len);
this.data.copy(buf, 0, pos, pos + len);
return String(buf).split("\t");
}
}
return null;
}
bytes2Uint32(a, b, c, d) {
let v = (a << 24 | b << 16 | c << 8 | d)
if (v < 0) {
return v + 4294967296;
} else {
return v;
}
}
}