c/c++查询纯真ip数据库类源代码

作者: admin 分类: C++ 发布时间: 2013-02-01 10:35 ė3,264 浏览数 6没有评论
文章转自王牌软件
站长推荐:NSetup一键部署软件
一键式完成美化安装包制作,自动增量升级,数据统计,数字签名。应对各种复杂场景,脚本模块化拆分,常规复杂的脚本代码,图形化设置。无需专业的研发经验,轻松完成项目部署。(www.nsetup.cn)

[ccein_cpp]//IPSearch.h /***************************************************************** * 访问纯真IP数据库(参考:纯真IP数据库格式详解) * * * * www.softwareace.cn * * usage: QQWry.Dat * * * * date : 2013/2/01 * *****************************************************************/ #include<stdio.h> #include<stdlib.h> #include<string.h> #define STRLEN 256 #define REDIRECT_MODE_1 0×01 #define REDIRECT_MODE_2 0×02 #define byte unsigned char //无符号型 #define ulong unsigned long //IP记录由country、area两部分组成 typedef struct IPLocation { byte country[STRLEN]; byte area[STRLEN]; }IPLocation; //纯真IP数据库头 typedef struct dbHeader { ulong firstStartIpOffset; ulong lastStartIpOffset; }dbHeader; //dbHeader dbheader; //IP数据库头 class IPSearch { public: IPSearch(); ~IPSearch(); // 将纯真IP数据库中的所有数据读入全局数组data int init(byte* file); // 查询ipStr IPLocation queryIp(byte* ipStr); // 二分法获得IP记录偏移量 ulong getOffsetOfIp(ulong ip); // 从索引区获得IP地址 ulong getIpFromIndex(ulong left,ulong* addr); // 从记录区获得IP地址 ulong getIpFromRecord(ulong endIpOff); // 将字符数组转成一个整数 ulong getInt32(byte* buf,int num); // 将ip从字符串形式转化为一个长整数 ulong IpToLong(byte* ipStr); // 给定一个ip国家地区记录的偏移,返回一个IPLocation结构 IPLocation getIPLocation(ulong offset); // 从offset偏移开始解析后面的字节,读出一个地区名 int readArea(ulong offset,byte* buf); // 将纯真IP数据库中的所有数据读入全局数组data int readString(ulong offset,byte* buf); // 输出要查询的IP记录 void Show(); private: byte* data; //指向纯真IP数据库的指针 IPLocation iplocation; //IP记录由country、area两部分组成 dbHeader dbheader; //IP数据库头 }; //IPSearch.cpp #include “IPSearch.h” IPSearch::IPSearch() { this->data = 0; //指向纯真IP数据库的指针 } IPSearch::~IPSearch() { } // 功能:将纯真IP数据库中的所有数据读入全局数组data // 参数:file 文件字符串 // 返回值: 0 成功 int IPSearch::init(byte* file) { ulong fileSize; //文件长度 FILE* fp; fp = fopen((char*)file,”rb”); if(fp == NULL) return 1; //获取文件长度 fseek(fp, 0, SEEK_END); fileSize = ftell(fp); //将纯真IP数据库中的所有数据读入数组 data=(byte*)malloc(fileSize* sizeof(byte)); fseek(fp,0,SEEK_SET); fread(data,1,fileSize,fp); if(data == NULL) return 2; fclose(fp); fp=NULL; //读取IP数据库文件头 dbheader.firstStartIpOffset=getInt32(&data[0],4); dbheader.lastStartIpOffset=getInt32(&data[4],4); //printf(“%ld %ld n”,dbheader.firstStartIpOffset,dbheader.lastStartIpOffset); return 0; } // 功能:查询ipStr IPLocation IPSearch::queryIp(byte* ipStr) { ulong ip; ulong offset; if(init((byte*)”QQWry.Dat”)==1) { printf(“QQWry.Dat 初始化失败!n”); } ip=IpToLong(ipStr); offset=getOffsetOfIp(ip); //printf(“ip:%u ,offset: %u”,ip,offset); return getIPLocation(offset); } //功能: 二分法获得IP记录偏移量 //参数:ip 待查询ip //返回值:相对于文件头的偏移量 (0 失败) ulong IPSearch::getOffsetOfIp(ulong ip) { ulong low=0; ulong high=(dbheader.lastStartIpOffset-dbheader.firstStartIpOffset)/7; ulong endIpOff; ulong mid; while(low<high-1) { mid=(low+high)/2; if(ip<getIpFromIndex(mid,&endIpOff)) high=mid; else low=mid; } //printf(“nlow:%ld n”,low); if(ip>=getIpFromIndex(low,&endIpOff)&&ip<=getIpFromRecord(endIpOff)) { return endIpOff; } return 0L; } // 功能:从索引区获得IP地址 // 参数:left 索引 // 返回值:起始Ip地址 // endIpOff 该索引所对应的结束Ip偏移量 ulong IPSearch::getIpFromIndex(ulong left,ulong* addr) { ulong leftOffset = dbheader.firstStartIpOffset + (left * 7L); *addr=getInt32(&data[leftOffset+4],3); return getInt32(&data[leftOffset],4); } // 功能:从记录区获得IP地址 ulong IPSearch::getIpFromRecord(ulong endIpOff) { return getInt32(&data[endIpOff],4); } // 功能:将字符数组转成一个整数 ulong IPSearch::getInt32(byte* buf,int num) { ulong ret=0; int i; for(i=0;i<num;i++) { ret+=(buf[i]<<(8*i)); } return ret ; } //将ip从字符串形式转化为一个长整数 ulong IPSearch::IpToLong(byte* ipStr) { byte* p=ipStr; byte ch; int i=0; int shift=24; ulong ret=0,temp; for(i=0;i<4;i++) { temp=0; while((ch=*p++)!=’.’ && ch) temp=temp*10+(ch -’0′); ret+=(temp<<shift); shift-=8; } if(i!=4) return -1; return ret; } // 功能:给定一个ip国家地区记录的偏移,返回一个IPLocation结构 // 参数: offset 国家记录的起始偏移 // 返回值:IPLocation对象 IPLocation IPSearch::getIPLocation(ulong offset) { byte flag_char; // 跳过4字节ip,读取随后字节判断是否为标志字节 flag_char=data[offset+4]; if(flag_char == REDIRECT_MODE_1) { // 读取国家偏移(3个字节) ulong countryOffset=getInt32(&data[offset+5],3); // 再检查一次标志字节,因为这个时候这个地方仍然可能是个重定向 flag_char=data[countryOffset]; if(flag_char == REDIRECT_MODE_2) { // 读取国家偏移 int temp; temp=getInt32(&data[countryOffset+1],3); readString(temp,iplocation.country); } else readString(countryOffset,iplocation.country); // 读取地区标志 readArea(countryOffset+4,iplocation.area); } else if(flag_char == REDIRECT_MODE_2) { ulong countryOffset=getInt32(&data[offset+5],3); readString(countryOffset,iplocation.country); readArea(offset + 8,iplocation.area); } else { readString(offset+4,iplocation.country) ; readArea(offset+4+strlen((char*)iplocation.country)+1,iplocation.area); } return iplocation; } // 功能:从offset偏移开始解析后面的字节,读出一个地区名 // 参数:offset 地区记录的起始偏移 // 返回值:0 成功 , 1 失败 int IPSearch::readArea(ulong offset,byte* buf) { byte flag_char; flag_char=data[offset]; if(flag_char== REDIRECT_MODE_1 || flag_char == REDIRECT_MODE_2) { ulong areaOffset=getInt32(&data[offset+1],3); readString(areaOffset,buf); } else { readString(offset,buf); } return 0; } // 功能:从offset偏移处读取一个以0结束的字符串至buf中 // 参数: offset 字符串起始偏移 // 返回值:0 成功 1 失败 int IPSearch::readString(ulong offset,byte* buf) { int i; buf[0]=data[offset]; for(i = 0; buf[i] != 0;) { i++; offset++; buf[i] = data[offset]; } if(i != 0) return 0; return 1; } // 功能:显示要查询的ip记录 void IPSearch::Show() { printf(“n%st%sn”,iplocation.country,iplocation.area); } //test.cpp #include <iostream> #include <stdio.h> #include <stdlib.h> #include “IPSearch.h” int main() { byte ip[20]; IPSearch *ipsearch = new IPSearch; while (1) { printf(“Please input ip to search : “); scanf(“%s”,ip); //输入t结束while循环 if (!strcmp((char*)ip, “t”)) { break; } ipsearch->queryIp(ip); ipsearch->Show(); } getchar(); return 0; } [/ccein_cpp]



只回答业务咨询点击这里给我发消息 点击这里给我发消息

王牌软件,兼职软件设计,软件修改,毕业设计。

本文出自 王牌软件,转载时请注明出处及相应链接。

本文永久链接: http://www.softwareace.cn/?p=158

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">


Ɣ回顶部

无觅相关文章插件,快速提升流量