version ip compare is ready
This commit is contained in:
parent
6c463282d0
commit
e924a7c17d
|
|
@ -28,3 +28,22 @@ test('parse ip address', () => {
|
||||||
console.log(`parseIP(${ipString}): {Bytes: ${toByte}, String: ${to_Str}}`);
|
console.log(`parseIP(${ipString}): {Bytes: ${toByte}, String: ${to_Str}}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('ip compare', () => {
|
||||||
|
let ip_list = [
|
||||||
|
["1.0.0.0", "1.0.0.1", -1],
|
||||||
|
["192.168.1.101", "192.168.1.90", 1],
|
||||||
|
["219.133.111.87", "114.114.114.114", 1],
|
||||||
|
["2000::", "2000:ffff:ffff:ffff:ffff:ffff:ffff:ffff", -1],
|
||||||
|
["2001:4:112::", "2001:4:112:ffff:ffff:ffff:ffff:ffff", -1],
|
||||||
|
["ffff::", "2001:4:ffff:ffff:ffff:ffff:ffff:ffff", 1]
|
||||||
|
];
|
||||||
|
|
||||||
|
ip_list.forEach(ips => {
|
||||||
|
const ip1 = util.parseIP(ips[0]);
|
||||||
|
const ip2 = util.parseIP(ips[1]);
|
||||||
|
const cmp = util.ipCompare(ip1, ip2);
|
||||||
|
expect(cmp).toBe(ips[2]);
|
||||||
|
console.log(`compare(${ips[0]}, ${ips[1]}): ${cmp}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -19,3 +19,27 @@ test("test version from name", () => {
|
||||||
console.log(`versionFrom(${ele})`, v == null ? null : v.toString());
|
console.log(`versionFrom(${ele})`, v == null ? null : v.toString());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("test version ip compare", () => {
|
||||||
|
let ip_list = [
|
||||||
|
["1.0.0.0", "0.0.1.2", 1],
|
||||||
|
["192.168.1.101", "192.168.1.90", 1],
|
||||||
|
["219.133.111.87", "114.114.114.114", 1],
|
||||||
|
["2000::", "2000:ffff:ffff:ffff:ffff:ffff:ffff:ffff", -1],
|
||||||
|
["2001:4:112::", "2001:4:112:ffff:ffff:ffff:ffff:ffff", -1],
|
||||||
|
["ffff::", "2001:4:ffff:ffff:ffff:ffff:ffff:ffff", 1]
|
||||||
|
];
|
||||||
|
|
||||||
|
ip_list.forEach(ips => {
|
||||||
|
const ip1 = util.parseIP(ips[0]);
|
||||||
|
const ip2 = util.parseIP(ips[1]);
|
||||||
|
if (ip1.length != ip2.length) {
|
||||||
|
fail(`ip1 and ip2 are not the same ip type`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = ip1.length == 4 ? util.IPv4 : util.IPv6;
|
||||||
|
const cmp = version.ipSubCompare(ip1, ip1.length == 4 ? ip2.reverse() : ip2, 0);
|
||||||
|
expect(cmp).toBe(ips[2]);
|
||||||
|
console.log(`compare(${ips[0]}, ${ips[1]}): ${cmp}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
// --- header
|
|
||||||
const XdbStructure20 = 2;
|
const XdbStructure20 = 2;
|
||||||
const XdbStructure30 = 3;
|
const XdbStructure30 = 3;
|
||||||
const XdbIPv4Id = 4;
|
const XdbIPv4Id = 4;
|
||||||
|
|
@ -80,15 +79,13 @@ class Header {
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
// ---
|
|
||||||
// version
|
|
||||||
class Version {
|
class Version {
|
||||||
constructor(id, name, bytes, indexSize, ip_compare_func) {
|
constructor(id, name, bytes, indexSize, ipCompareFunc) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.bytes = bytes;
|
this.bytes = bytes;
|
||||||
this.indexSize = indexSize;
|
this.indexSize = indexSize;
|
||||||
this.ip_compare_func = ip_compare_func;
|
this.ipCompareFunc = ipCompareFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
id() {
|
id() {
|
||||||
|
|
@ -108,11 +105,15 @@ class Version {
|
||||||
}
|
}
|
||||||
|
|
||||||
compareFunc() {
|
compareFunc() {
|
||||||
return this.ip_compare_func;
|
return this.ipCompareFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipCompare(ip1, ip2) {
|
ipCompare(ip1, ip2) {
|
||||||
return this.ip_compare_func(ip1, ip2);
|
return this.ipCompareFunc(ip1, ip2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipSubCompare(ip1, ip2, offset) {
|
||||||
|
return this.ipCompareFunc(ip1, ip2, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
|
|
@ -121,12 +122,28 @@ class Version {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14 = 4 + 4 + 2 + 4
|
// 14 = 4 + 4 + 2 + 4
|
||||||
const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, ip2){
|
const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){
|
||||||
|
// ip1: Big endian byte order parsed from input
|
||||||
|
// ip2: Little endian byte order read from xdb index.
|
||||||
|
// @Note: to compatible with the old Litten endian index encode implementation.
|
||||||
|
let i, j = offset + ip1.length - 1;
|
||||||
|
for (i = 0; i < ip1.length; i++, j--) {
|
||||||
|
const i1 = ip1[i] & 0xFF;
|
||||||
|
const i2 = buff[j] & 0xFF;
|
||||||
|
if (i1 < i2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i1 > i2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 38 = 16 + 16 + 2 + 4
|
// 38 = 16 + 16 + 2 + 4
|
||||||
const IPv6 = new Version(XdbIPv6Id, "IPv6", 6, 38, function(ip1, ip2){
|
const IPv6 = new Version(XdbIPv6Id, "IPv6", 6, 38, ipSubCompare);
|
||||||
});
|
|
||||||
|
|
||||||
function versionFromName(name) {
|
function versionFromName(name) {
|
||||||
let n = name.toUpperCase();
|
let n = name.toUpperCase();
|
||||||
|
|
@ -163,9 +180,6 @@ function versionFromHeader(h) {
|
||||||
}
|
}
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
// ---
|
|
||||||
// parse the specified string ip and return its bytes
|
|
||||||
|
|
||||||
// parse ipv4 address
|
// parse ipv4 address
|
||||||
function _parse_ipv4_addr(v4String) {
|
function _parse_ipv4_addr(v4String) {
|
||||||
let ps = v4String.split('.', 4);
|
let ps = v4String.split('.', 4);
|
||||||
|
|
@ -229,7 +243,6 @@ function _parse_ipv6_addr(v6String) {
|
||||||
dc_num = 1;
|
dc_num = 1;
|
||||||
// padding = 8 - start - left
|
// padding = 8 - start - left
|
||||||
let padding = 8 - start - (mi - i);
|
let padding = 8 - start - (mi - i);
|
||||||
// console.log(`i=${i}, padding=${padding}`);
|
|
||||||
offset += 2 * padding;
|
offset += 2 * padding;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -243,7 +256,6 @@ function _parse_ipv6_addr(v6String) {
|
||||||
throw new Error(`invalid ipv6 part '${ps[i]}' should >= 0 and <= 65534`);
|
throw new Error(`invalid ipv6 part '${ps[i]}' should >= 0 and <= 65534`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(`${i}: v=${v}, offset=${offset}`);
|
|
||||||
ipBytes.writeUint16BE(v, offset);
|
ipBytes.writeUint16BE(v, offset);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
}
|
}
|
||||||
|
|
@ -252,6 +264,7 @@ function _parse_ipv6_addr(v6String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// parse the specified string ip and return its bytes
|
||||||
// @param ip string
|
// @param ip string
|
||||||
// @return Buffer
|
// @return Buffer
|
||||||
function parseIP(ipString) {
|
function parseIP(ipString) {
|
||||||
|
|
@ -268,9 +281,6 @@ function parseIP(ipString) {
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
// ---
|
|
||||||
// bytes ip to humen-readable string ip
|
|
||||||
|
|
||||||
// ipv4 bytes to string
|
// ipv4 bytes to string
|
||||||
function _ipv4_to_string(v4Bytes) {
|
function _ipv4_to_string(v4Bytes) {
|
||||||
return v4Bytes.join('.');
|
return v4Bytes.join('.');
|
||||||
|
|
@ -291,7 +301,6 @@ function _ipv6_to_string(v6Bytes, compress) {
|
||||||
let j = 0, mi = ps.length - 1;
|
let j = 0, mi = ps.length - 1;
|
||||||
let _ = [];
|
let _ = [];
|
||||||
for (i = 0; i < ps.length; i++) {
|
for (i = 0; i < ps.length; i++) {
|
||||||
// console.log(`i=${i}, v=${ps[i]}`);
|
|
||||||
if (i >= mi || j > 0) {
|
if (i >= mi || j > 0) {
|
||||||
_.push(ps[i]);
|
_.push(ps[i]);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -325,10 +334,10 @@ function _ipv6_to_string(v6Bytes, compress) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(`ps.length=${ps.length}, _.length=${_.length}`);
|
|
||||||
return _.join(':');
|
return _.join(':');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bytes ip to humen-readable string ip
|
||||||
function ipToString(ipBytes, compress) {
|
function ipToString(ipBytes, compress) {
|
||||||
if (!Buffer.isBuffer(ipBytes)) {
|
if (!Buffer.isBuffer(ipBytes)) {
|
||||||
throw new Error('invalid bytes ip, not a Buffer');
|
throw new Error('invalid bytes ip, not a Buffer');
|
||||||
|
|
@ -343,7 +352,6 @@ function ipToString(ipBytes, compress) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// print ip bytes
|
|
||||||
function ipBytesString(ipBytes) {
|
function ipBytesString(ipBytes) {
|
||||||
if (!Buffer.isBuffer(ipBytes)) {
|
if (!Buffer.isBuffer(ipBytes)) {
|
||||||
throw new Error('invalid bytes ip, not a Buffer');
|
throw new Error('invalid bytes ip, not a Buffer');
|
||||||
|
|
@ -354,17 +362,20 @@ function ipBytesString(ipBytes) {
|
||||||
ps.push(ipBytes[i] & 0xFF);
|
ps.push(ipBytes[i] & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
return ps.join('.');
|
return ps.join('.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// compare two byte ips
|
// compare two byte ips
|
||||||
|
// ip2 = buff[offset:ip1.length]
|
||||||
// returns: -1 if ip1 < ip2, 1 if ip1 > ip2 or 0
|
// returns: -1 if ip1 < ip2, 1 if ip1 > ip2 or 0
|
||||||
function ipCompare(ip1, ip2) {
|
function ipSubCompare(ip1, buff, offset) {
|
||||||
|
return ip1.compare(buff, offset, offset + ip1.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ipCompare(ip1, ip2) {
|
||||||
|
return ipSubCompare(ip1, ip2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load header from xdb file
|
|
||||||
function loadHeader(fd) {
|
function loadHeader(fd) {
|
||||||
const buffer = Buffer.alloc(HeaderInfoLength);
|
const buffer = Buffer.alloc(HeaderInfoLength);
|
||||||
const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0);
|
const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0);
|
||||||
|
|
@ -420,14 +431,14 @@ module.exports = {
|
||||||
// header
|
// header
|
||||||
XdbStructure20, XdbStructure30, XdbIPv4Id, XdbIPv6Id,
|
XdbStructure20, XdbStructure30, XdbIPv4Id, XdbIPv6Id,
|
||||||
HeaderInfoLength, VectorIndexRows, VectorIndexCols, VectorIndexSize,
|
HeaderInfoLength, VectorIndexRows, VectorIndexCols, VectorIndexSize,
|
||||||
Header,
|
|
||||||
|
|
||||||
// version
|
// version
|
||||||
Version, IPv4, IPv6,
|
IPv4, IPv6,
|
||||||
versionFromName, versionFromHeader,
|
versionFromName, versionFromHeader,
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
parseIP, ipToString, ipBytesString, ipCompare,
|
parseIP, ipToString, ipBytesString,
|
||||||
|
ipSubCompare, ipCompare,
|
||||||
loadHeader, loadHeaderFromFile,
|
loadHeader, loadHeaderFromFile,
|
||||||
loadVectorIndex, loadVectorIndexFromFile,
|
loadVectorIndex, loadVectorIndexFromFile,
|
||||||
loadContent, loadContentFromFile
|
loadContent, loadContentFromFile
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue