ip2region小问题修复发
By
money
at 2022-01-20 • 0人收藏 • 829人看过
在https://suiang.cn/ 发现一个ip2region库,一直用得非常愉快,直到在windowsServer2016中运行,ip2region.db置于中文目录下,会报错,无法读取文件,只需要将程序置于英文目录就简单解决,但是我这贱人的小矫情控制不住(win10没问题,其它系统没测)
/* https://gitee.com/lionsoul/ip2region */ import wsock import fsys.file; namespace inet; class ip2region{ ctor( path ){ path := "~\lib\inet\ip2region\.res\ip2region.db" this.file, err = ..fsys.file(path, "rb") if(!this.file){ return null,err; } this.headerLen = 0; this.HeaderSip = {}; this.HeaderPtr = {}; //open the db file this.firstIndex = 0; this.lastIndex = 0; this.totalBlocks= 0; this.dbBinStr = null; ..table.add_gc(this,"close"); }; memory_search = function(ip) { if ( !this.dbBinStr ) { //alloc the buffer size this.file.seek("set") this.dbBinStr = ..raw.buffer(this.file.readAll()); var index = ..raw.convert(this.dbBinStr, {INT beginIndex; INT endIndex}) this.firstIndex = index.beginIndex; this.lastIndex = index.endIndex; this.totalBlocks = (this.lastIndex-this.firstIndex)/INDEX_BLOCK_LENGTH + 1; } var left = 0; var right = this.totalBlocks; var dptr = 0; while ( left <= right ) { var middle = (left + right) >> 1; //二分法 var offset = this.firstIndex + middle * INDEX_BLOCK_LENGTH; sip = ..raw.convert(this.dbBinStr, {INT ip}, offset).ip if ( ip < sip ) { right = middle - 1; } else { eip = ..raw.convert(this.dbBinStr, {INT ip}, offset+4).ip if ( ip > eip ) { left = middle + 1; } else { dptr = ..raw.convert(this.dbBinStr, {INT ip}, offset + 8).ip break; } } } if ( dptr == 0 ) return; var dataLen = ((dptr >> 24) & 0xFF); var dataptr = (dptr & 0x00FFFFFF); var city_id = ..raw.convert(this.dbBinStr, {INT id}, dataptr).id; return { city_id = city_id; region = ..string.slice(this.dbBinStr, dataptr+4+1, dataptr+dataLen) }; } btree_search = function(ip){ var (i, idx) var (l, m, h, p, sptr, eptr, indexBlockLen, dataLen, dataptr) var (sip, eip, idxptr, dptr); if ( !this.headerLen ) { var buf = ..raw.buffer(TOTAL_HEADER_LENGTH); this.file.seek("set",8) this.file.readBuffer(buf); var idx = 0; for(i=1; TOTAL_HEADER_LENGTH; 8){ idx++; var head = ..raw.convert(buf, {int sip;int idxptr}, i-1); if(!head.idxptr){ break } this.HeaderSip[idx] = head.sip; this.HeaderPtr[idx] = head.idxptr; } this.headerLen = idx; } //search the header block to define the index block var (l = 0; h = this.headerLen; sptr = 0; eptr = 0;) while ( l <= h ) { m = ((l + h) >> 1); //perfetc matched, just return it if ( ip == this.HeaderSip[m] ) { if ( m > 0 ) { sptr = this.HeaderPtr[m-1]; eptr = this.HeaderPtr[m ]; } else { sptr = this.HeaderPtr[m ]; eptr = this.HeaderPtr[m+1]; } break; } //less then the middle value if ( ip < this.HeaderSip[m] ) { if ( m == 0 ) { sptr = this.HeaderPtr[m ]; eptr = this.HeaderPtr[m+1]; break; } else if ( ip > this.HeaderSip[m-1] ) { sptr = this.HeaderPtr[m-1]; eptr = this.HeaderPtr[m ]; break; } h = m - 1; } else { if ( m == this.headerLen - 1 ) { sptr = this.HeaderPtr[m-1]; eptr = this.HeaderPtr[m ]; break; } else if ( ip <= this.HeaderSip[m+1] ) { sptr = this.HeaderPtr[m ]; eptr = this.HeaderPtr[m+1]; break; } l = m + 1; } } //not matched just stop it if ( sptr == 0 ) return ; var indexBlockLen = eptr - sptr; this.file.seek("set", sptr); var buf = ..raw.buffer(indexBlockLen + INDEX_BLOCK_LENGTH) if(!this.file.readBuffer(buf)){ return ; } var (dptr = 0; l = 0; h = indexBlockLen / INDEX_BLOCK_LENGTH;) while ( l <= h ) { m = ((l + h) >> 1); p = m * INDEX_BLOCK_LENGTH; sip = ..raw.convert(buf, {int sip}, p) sip = sip.sip if ( ip < sip ) { h = m - 1; } else { eip = ..raw.convert(buf, {int eip}, p+4) eip = eip.eip if ( ip > eip ) { l = m + 1; } else { dptr = ..raw.convert(buf, {int dptr}, p+8) dptr = dptr.dptr break; } } } if ( dptr == 0 ) return 0; dataLen = ((dptr >> 24) & 0xFF); dataptr = (dptr & 0x00FFFFFF); this.file.seek("set", dataptr) var city_id = this.file.read({INT id}).id; return { city_id = city_id; region = this.file.read(dataLen-4); }; } close = function(){ if(this.file){ this.file.close(); this.file=null } }; string2ip = function (str){ return ..wsock.htonl(..wsock.inet_addr(str)) }; getIpInfo = function(ip, mode = "btree") { var search = this[[mode+"_search"]] if(type(search)!==type.function){ return; } if (!owner.isValidIp(ip)) return; var ipInfo = IpInfo() ip = this.string2ip(ip) var data = search(ip) if (data) { var arr = split(data.region, "|") if (# arr = 5) { ipInfo.CityId = data.city_id ipInfo.Country = arr[1] ipInfo.Region = arr[2] ipInfo.Province = arr[3] ipInfo.City = arr[4] ipInfo.ISP = arr[5] } } return ipInfo }; isValidIp = function(s) { return match(s, "\d+\.\d+\.\d+\.\d+") ? true : false }; } namespace ip2region{ INDEX_BLOCK_LENGTH=12; TOTAL_HEADER_LENGTH=8192; match = ..string.match; concat = ..string.concat; split = ..string.split; class IpInfo { CityId=0; Country=""; Region=""; Province=""; City=""; ISP=""; @_meta; } IpInfo._meta = { _tostring = function() { return concat(owner.Country, owner.Province, owner.City, " ", owner.ISP) } } import web.rest.client; var http = web.rest.client(); getIp = function() { return http.api("https://www.taobao.com/help/getip.php", "GET", "\d+\.\d+\.\d+\.\d+")(); } } /**intellisense() inet.ip2region = ip2region数据库 inet.ip2region() = 创建IP数据库连接\n!inet_ip2region. !inet_ip2region.getIpInfo( = 查询IP归属性 !inet_ip2region.getIpInfo(.("IP地址") = 返回IP归属地 !inet_ip2region.close() = 关闭数据库连接 end intellisense**/
1 个回复 | 最后更新于 2022-01-20
登录后方可回帖
矫情,哈哈