为了庆祝AIR正式版发布(不是正式版这个还做不了,不信你试试,哈),在此献上AS3.0版本的读取QQwry.dat显IP地址所属地区程序。 教程目的: 熟悉AIR的文件操作方式(个人感觉类似c#,但没c#强大),至于这个东东有什么用,我想不用我多说。 开始: 首先请各位先了解QQwry.dat的文件格式.个人认为这个地址讲的最好:http://www.cnblogs.com/tobylee/archive/2005/12/13/296362.html 下载QQwry.dat,大家上网上搜吧,6m左右 然后: 一个类
复制内容到剪贴板
代码:
package { public class IpInfo { public var ipBegin:Number; public var ipOffset:Number; public var ipEnd:Number; } }
AIR主程序
复制内容到剪贴板
代码:
import flash.filesystem.*; private var file:File; private var fileStream:FileStream; private var ipIndexBeginOffSet:uint; private var ipIndexEndOffSet:uint; private var ipBlockCount:Number; private var searchBeginIpInfo:IpInfo=new IpInfo(); private var searchEndIpInfo:IpInfo=new IpInfo(); private var searchMidIpInfo:IpInfo=new IpInfo(); private var searchBeginPos:uint; private var searchEndPos:uint; private function init():void { //注意QQWry.dat的地址 file=File.applicationDirectory.resolvePath("QQWry.dat"); fileStream=new FileStream(); fileStream.open(file,FileMode.READ); fileStream.endian=Endian.LITTLE_ENDIAN; var byteArr:ByteArray=new ByteArray(); fileStream.readBytes(byteArr,0,8); ipIndexBeginOffSet=byteArr[0]+(byteArr[1]<<8)+(byteArr[2]<<16)+(byteArr[3]<<24); ipIndexEndOffSet=byteArr[4]+(byteArr[5]<<8)+(byteArr[6]<<16)+(byteArr[7]<<24); ipBlockCount=(ipIndexEndOffSet-ipIndexBeginOffSet)/7+1; //设置二分查找法的头和尾 this.searchBeginPos=0; this.searchEndPos=ipBlockCount-1; //加这句,不然乱码 System.useCodePage=true; //这里修改你要查找的ip地址 trace(searchIpInfo("218.240.16.20")); } //二分查找法搜索索引区 private function searchIpInfo(ip:String):String { var subIp:Number=ipToNumber(ip); while (true) { //头 searchBeginIpInfo=getIpInfo(this.searchBeginPos); //尾 searchEndIpInfo=getIpInfo(this.searchEndPos); if (subIp>searchBeginIpInfo.ipBegin && subIp<searchBeginIpInfo.ipEnd) return readAddressInfo(searchBeginIpInfo.ipOffset); if (subIp>searchEndIpInfo.ipBegin && subIp<searchEndIpInfo.ipEnd) return readAddressInfo(searchEndIpInfo.ipOffset); searchMidIpInfo=getIpInfo((this.searchBeginPos+this.searchEndPos)/2) if (subIp>searchMidIpInfo.ipBegin && subIp<searchMidIpInfo.ipEnd) return readAddressInfo(searchMidIpInfo.ipOffset); if (subIp>searchMidIpInfo.ipEnd) { this.searchBeginPos=(this.searchBeginPos+this.searchEndPos)/2; } else { this.searchEndPos=(this.searchBeginPos+this.searchEndPos)/2; } } return ""; } //读取该 private function readAddressInfo(pos:uint):String { var country:String=""; var area:String=""; var countryOffset:Number=0; var tag:uint; fileStream.position=pos+4; //读取模式 tag=readTag(); if (tag==1) { //当模式为1的时候,指向改偏移地址 fileStream.position=getIpOffset(); tag=readTag(); //国家模式为2 if (tag==2) { countryOffset=getIpOffset(); area=this.readArea(); fileStream.position=countryOffset; country=this.readString(); } else { fileStream.position-=1; country=this.readString(); area=this.readArea(); } } else if (tag==2) { //当模式为2的时候,指向改偏移地址 countryOffset=getIpOffset(); //先读取地区** area=this.readArea(); //再读取国家 fileStream.position=countryOffset; country=this.readString(); } else { fileStream.position-=1; country=this.readString(); area=this.readArea(); } var address:String=country+" "+area; return address; } //读取记录模式 private function readTag():uint { return fileStream.readByte(); } //读取地区 private function readArea():String { var tag:uint=readTag(); if (tag==1 || tag==2) { fileStream.position=getIpOffset(); return readString(); } else { fileStream.position-=1; return readString(); } } //读取fileStream的数据 private function readString():String { var subOffset:uint=0; var stringArr:ByteArray=new ByteArray(); stringArr[subOffset]=fileStream.readByte(); while (stringArr[subOffset]!=0) { subOffset++; stringArr[subOffset]=fileStream.readByte(); } return stringArr.toString(); } //根据参数pos(记录点)读取改记录的起始ip,偏移地址和结束ip; private function getIpInfo(pos:uint):IpInfo { fileStream.position=this.ipIndexBeginOffSet+7*pos; var subIpInfo:IpInfo=new IpInfo(); subIpInfo.ipBegin=getIpNum(); subIpInfo.ipOffset=getIpOffset(); fileStream.position=subIpInfo.ipOffset; subIpInfo.ipEnd=getIpNum(); return subIpInfo; } //读取ip地址 private function getIpNum():Number { var byteArr:ByteArray=new ByteArray(); fileStream.readBytes(byteArr,0,4); //return byteArr[0]|(byteArr[1]<<8)|(byteArr[2]<<16)|(byteArr[3]<<24); //return byteArr[0].toString()+(byteArr[1]<<8).toString()+ //(byteArr[2]<<16)+(byteArr[3]<<24); return byteArr[0]+byteArr[1]*256+byteArr[2]*256*256+byteArr[3]*256*256*256; } //读取偏移地址 private function getIpOffset():Number { var byteArr:ByteArray=new ByteArray(); fileStream.readBytes(byteArr,0,3); return byteArr[0]+byteArr[1]*256+byteArr[2]*256*256; } //ip转换为数值 private function ipToNumber(ip:String):uint { var ipArr:Array=ip.split("."); if (ipArr.length==4) { var _n:uint=(uint(ipArr[0]<<24))+(uint(ipArr[1]<<16))+(uint(ipArr[2]<<8))+uint(ipArr[3]); return _n; } else { return 0; } }
附录源文件 马上点击下载
|