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
2022-01-20   #1

矫情,哈哈

登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...