UNPKG

qqwry-lite

Version:

qqwry.dat for node (node 纯真 IP 库)

172 lines (166 loc) 5.22 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var fs = require('fs'); var gbk_js = require('gbk.js'); var IP_RECORD_LENGTH = 7; // IP 记录数据长度 var REDIRECT_MODE_1 = 1; var REDIRECT_MODE_2 = 2; /** * IP转正数 * @param ip */ function ip2int(ip) { var bytes = ip.split('.').map(function (n) { return parseInt(n, 10); }); var addr = bytes[3] & 0xff; addr |= (bytes[2] << 8) & 0xff00; addr |= (bytes[1] << 16) & 0xff0000; addr |= (bytes[0] << 24) & 0xff000000; return addr >>> 0; } /** * 取得 begin 和 end 中间的偏移 (用于2分法查询) * @param begin 其实位置 * @param end 结束位置 * @param recordLength 记录长度 */ function getMiddleOffset(begin, end, recordLength) { var records = (((end - begin) / recordLength) >> 1) * recordLength + begin; return records ^ begin ? records : records + recordLength; } /** * 2分法查找指定的IP偏移 * @param ip int 型 ip 值 * @param qqwry QQwry 实例 */ function locateIP(ip, qqwry) { var temp; var g = -1; var b = qqwry.ipBegin; var e = qqwry.ipEnd; for (; b < e;) { g = getMiddleOffset(b, e, IP_RECORD_LENGTH); //获取中间位置 temp = qqwry.buffer.readUIntLE(g, 4); if (ip > temp) { b = g; } else if (ip < temp) { if (g === e) { g -= IP_RECORD_LENGTH; return g; } e = g; } else { return g; } } return g; } // 读取 buffer 字符串 (GBK数据) function getStringByteArray(start, buffer) { if (start === void 0) { start = 0; } var maxSize = buffer.length; var toarr = []; for (var i = start; i < maxSize; i++) { var s = buffer[i]; if (s === 0) { return toarr; } toarr.push(s); } return toarr; } // 读取 Area 数据 function ReadArea(offset, buffer) { var one = buffer.readUIntLE(offset, 1); if (one == REDIRECT_MODE_1 || one == REDIRECT_MODE_2) { var areaOffset = buffer.readUIntLE(offset + 1, 3); if (areaOffset == 0) { return ''; } else { return gbk_js.decode(getStringByteArray(areaOffset, buffer)); } } else { return gbk_js.decode(getStringByteArray(offset, buffer)); } } /** * 获取 IP 地址对应区域 * @param offset 偏移 * @param buffer 数据库 */ function setIPLocation(offset, buffer) { var ipwz = buffer.readUIntLE(offset + 4, 3) + 4; var lx = buffer.readUIntLE(ipwz, 1); var loc = { addr: '', info: '' }; var Gjbut = []; if (lx === REDIRECT_MODE_1) { //Country根据标识再判断 ipwz = buffer.readUIntLE(ipwz + 1, 3); //读取国家偏移` lx = buffer.readUIntLE(ipwz, 1); //再次获取标识字节 if (lx == REDIRECT_MODE_2) { //再次检查标识字节 Gjbut = getStringByteArray(buffer.readUIntLE(ipwz + 1, 3), buffer); loc.addr = gbk_js.decode(Gjbut); // loc.addr = Gjbut.toString(); ipwz = ipwz + 4; } else { Gjbut = getStringByteArray(ipwz, buffer); loc.addr = gbk_js.decode(Gjbut); // loc.addr = Gjbut.toString(); ipwz += Gjbut.length + 1; } loc.info = ReadArea(ipwz, buffer); } else if (lx === REDIRECT_MODE_2) { //Country直接读取偏移处字符串 Gjbut = getStringByteArray(buffer.readUIntLE(ipwz + 1, 3), buffer); loc.addr = gbk_js.decode(Gjbut); // loc.addr = Gjbut.toString(); loc.info = ReadArea(ipwz + 4, buffer); } else { // Country 直接读取 Area 根据标志再判断 Gjbut = getStringByteArray(ipwz, buffer); ipwz += Gjbut.length + 1; loc.addr = gbk_js.decode(Gjbut); // loc.addr = Gjbut.toString(); loc.info = ReadArea(ipwz, buffer); } // 过滤信息 if (loc.info.indexOf('CZ88.NET') > -1) { loc.info = ''; } return loc; } var QQwry = /** @class */ (function () { /** * qqwry.dat 地址 * @param path 路径 */ function QQwry(path) { path = path || require('qqwry-lite-data'); this.buffer = fs.readFileSync(path); // 读取数据库 this.ipBegin = this.buffer.readUIntLE(0, 4); // 0-4 字节存储 数据库 起始位置 this.ipEnd = this.buffer.readUIntLE(4, 4); // 4-8 字节存储 数据库 结束位置 } /** * 搜索IP信息 * @param ip IP */ QQwry.prototype.searchIP = function (ip) { var ipInt = ip2int(ip); var offset = locateIP(ipInt, this); // 寻找 ip 偏移 if (offset === -1) { return { ip: ip, addr: '', info: '' }; } var _a = setIPLocation(offset, this.buffer), addr = _a.addr, info = _a.info; return { ip: ip, addr: addr, info: info }; }; return QQwry; }()); exports.QQwry = QQwry; exports.default = QQwry;