纯真IP数据库(QQWry.Dat)查询 C源码

本文介绍了一个使用C语言实现的纯真IP数据库(QQWry.Dat)查询程序。该程序支持IP地址查询、数据库导出及按名称搜索IP段等功能。文章提供了完整的源代码及编译说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

纯真ip数据库(QQWry.Dat)查询源代码C语言版

整理硬盘看到以前写的纯真ip数据库(QQWry.Dat)查询代码,觉得没有什么价值了,当时学习C语言的文件操作时自己的一个练习而已,现在公布出来希望对学习C语言的人有所参考价值.
纯真ip数据库(QQWry.Dat)是当年很多修改版QQ使用的显示对方所在地的ip数据库,该数据库由纯真维护着,ip地址所在地是许多网友提交才发展那么强大的,参考lumaqq的一些资料会有帮助:

纯真ip地址查询java代码 
lumaqq文档整理

好了不多说了代码如下:
MakeFile

CC      = gcc.exe
BIN     = qqwry.exe
WINDRES = windres.exe
RES     = resource.o
OBJ     = main.o qqwry.o localIp.o $(RES)
# D:\MinGW\lib\libwsock32.a
LIBS =  -L"D:/MinGW/lib"-lwsock32
RM      = del -f
 
$(BIN): $(OBJ)
    $(CC) -o $(BIN) $(OBJ) $(RES) $(LIBS)
 
main.o: main.h qqwry.h
qqwry.o: qqwry.h localIp.h
localIp.o: localIp.h
 
$(RES): resource.rc my_icon.ico
    $(WINDRES) -o $(RES) resource.rc
 
.PHONY:clean
clean:
    $(RM) $(BIN) $(OBJ) *~
main.c
/**
 *
 * 增加了解压数据库功能,包括
 * void readIpString(char *string);
 * void exportData(char *fileName);
 *
 * @author http://www.heui.org
 * @version 0.6
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "qqwry.h"
 
FILE*ipFile         = NULL; //ip文件指针
unsigned longipBegin  = 0; //ip开始地址
unsigned longipEnd    = 0; //ip结束地址
unsigned longipSum    = 0; //ip总数
/**
 * main()
 */
int main(int argc, char** argv)
{
    ipFile = fopen("QQWry.Dat", "rb");
    if(!ipFile){
        puts("QQWry.Dat文件丢失");
        exit(1);
    }
    unsigned longdata[2];
    fread(data, 1, 8, ipFile);
    ipBegin = data[0];
    ipEnd = data[1];
    ipSum = ((data[1]-data[0])/RECORD_LENGTH +1);
 
    checkCmdLine(argc, argv);//处理命令行参数
 
    fclose(ipFile);
    return0;
}
qqwry.h
#ifndef QQWRY_H
#define QQWRY_H
 
#define RECORD_LENGTH 0x07  //ip记录长度
#define AREA_FOLLOWED 0X01  //模式1
#define NO_AREA       0x02  //模式2
 
typedefstructipInfo
{
    charipBegin[15];            //ip段开始地址
    charipEnd[15];              //ip段结束地址
    charcountryAndArea[255];   //ip段对应的国家和地区
} ipInfo;
 
unsigned longstringIpToLong(char*ipString);
unsigned longseekIpBinarySearch(char*ipString);
voidreadString(char*string, unsigned longoffset);
voidreadStringCur(char*string);
voidseekCountryArea(char*string, unsigned longoffset);
voidreadArea(char*string);
voidcheckCmdLine(intargc, char**argv);
voidreadIpString(char*string);
voidexportData(char*fileName);
voidsearchIpByName(char*name);
 
#endif
qqwry.c
/**
 * 重新写了stringIpToLong函数,改用sscanf,增加了判断ip地址错误
 * @author http://www.heui.org
 * @version 0.8
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
 
#include "qqwry.h"
#include "localIp.h"
 
externFILE*ipFile;
externunsigned longipBegin, ipEnd, ipSum;
 
/**
 * 把ip字符串转换为unsigned long
 * @param char *ipString
 * @return unsigned long ret
 */
unsigned longstringIpToLong(char*ipString)
{
    intnum[4];
    charch =0;
    unsigned longret = 0;
    if(sscanf(ipString, "%3d.%3d.%3d.%3d%c",&num[0], &num[1], &num[2], &num[3], &ch) != 4
          //  || ch != 0  //sscanf返回 !=4包括了ch不为0
            || num[0] > 0xFF
            || num[1] > 0xFF
            || num[2] > 0xFF
            || num[3] > 0xFF
            || num[0] < 0x00
            || num[1] < 0x00
            || num[2] < 0x00
            || num[3] < 0x00){
        puts("ip地址错误");
        exit(0);
    }
 
    ret = ret | (num[0] << 24) | (num[1] << 16) | (num[2] << <img src="http://www.heui.org/wp-includes/images/smilies/icon_cool.gif "alt="8)"class="wp-smiley"> | (num[3]);
    /*
        char tmp[16];
        unsigned long ret = 0;
        strcpy(tmp, ipString);
        char *str = strtok(tmp, ".");
        ret = ret | (atol(str) << 24);
        str = strtok(NULL, ".");
        ret = ret | (atol(str) << 16);
        str = strtok(NULL, ".");
        ret = ret | (atol(str) << 8);
        str = strtok(NULL, ".");
        ret = ret | (atol(str));
        */
    returnret;
}
 
/**
 * 返回ip记录所在位置,使用二分法
 * @param char *ipString
 * @return unsigned long
 */
unsigned longseekIpBinarySearch(char*ipString)
{
    unsigned longipNum = stringIpToLong(ipString);
    unsigned longstart = 0L;
    unsigned longend = ipSum;
    unsigned longmid = 0L;
    unsigned longaddr[2] = {0L};
 
    while(start != end) {
        mid = (start + end) / 2;
        fseek(ipFile, ipBegin + mid * RECORD_LENGTH, SEEK_SET);
        fread(addr, 1, 7, ipFile);
        if(ipNum == addr[0]) {
            returnaddr[1];
        } elseif(end == start +1) {
            returnaddr[1];
        } elseif(ipNum > addr[0]){
            start = mid;
        } else/* if(ipNum > addr[0])*/{
            end = mid;
        }
    }
 
}
 
/**
 * 从文件offset位置读取字符串到string,直到遇到空字符
 * @param char *string
 * @param unsigned long offset
 * @return void
 */
voidreadString(char*string, unsigned longoffset)
{
    fseek(ipFile, offset, SEEK_SET);
    while(*string++ = fgetc(ipFile))
        ;
}
 
/**
 * 从文件当前位置读取字符串到string,直到遇到空字符
 * @param char *string
 * @param unsigned long offset
 * @return void
 */
voidreadStringCur(char*string)
{
    while(*string++ = fgetc(ipFile))
        ;
}
/**
 * 从文件offset位置读取国家地区到string
 * @param char *string
 * @param unsigned long offset
 * @return void
 */
voidseekCountryArea(char*string, unsigned longoffset)
{
    fseek(ipFile, offset+4, SEEK_SET);
    charflag = fgetc(ipFile);
    unsigned longcountryOffset[1] = {0L};
    if(AREA_FOLLOWED == flag) {
        fread(countryOffset, 1, 3, ipFile);
        fseek(ipFile, countryOffset[0], SEEK_SET);
        flag = fgetc(ipFile);
        if(NO_AREA == flag) {
            unsigned longtmp = countryOffset[0];
            fread(countryOffset, 1, 3, ipFile);
            fseek(ipFile, countryOffset[0], SEEK_SET);
            readStringCur(string);
            string = strcat(string, " ");
            fseek(ipFile, tmp+4, SEEK_SET);
        } else{
            fseek(ipFile, -1, SEEK_CUR);
            readStringCur(string);
            string = strcat(string, " ");
 
        }
 
    } elseif(NO_AREA == flag){
        fread(countryOffset, 1, 3, ipFile);
        readString(string, countryOffset[0]);
        string = strcat(string, " ");
        fseek(ipFile, offset+8, SEEK_SET);
    } else{
        readString(string, offset+4);
        string = strcat(string, " ");
    }
    readArea(string);
}
 
/**
 * 读取地区字符串到string后面,具体是加在国家字符串后面
 * @param char *string
 * @return void
 */
voidreadArea(char*string)
{
 
    unsigned longoffset[1] = {0L};
    chararea[255] = "";
    int  flag = fgetc(ipFile);
    if(AREA_FOLLOWED == flag || NO_AREA == flag) {
        fread(offset, 1, 3, ipFile);
        readString(area, offset[0]);
        string = strcat(string, area);
    } else{
        fseek(ipFile, -1, SEEK_CUR);
        readStringCur(area);
        string = strcat(string, area);
    }
}
 
/**
 * 检查命令行输入参数
 */
voidcheckCmdLine(intargc, char**argv){
    if(argc == 1) {
        //数据库信息
        unsigned longll = seekIpBinarySearch("255.255.255.0");
        charstring[255]="";
        seekCountryArea(string,ll);
        printf("%s %lu条\n", string, ipSum);
 
        //输出你的ip地址
        localIp(string);
        printf("\n你的IP:%s\n",string);
        ll = seekIpBinarySearch(string);
        seekCountryArea(string,ll);
        printf("IP地址:%s\n",string);
 
        //帮助
        puts("----------------------------------------");
        puts("查询ip地址");
        printf("\n用法:\%s ip地址\n例如:%s 127.0.0.1\n", argv[0], argv[0]);
 
        puts("\n解压数据库");
        printf("\n用法:\%s -o 文件名\n例如:%s -o qqwry.txt\n", argv[0], argv[0]);
 
        puts("\n搜索字符串");
        printf("\n用法:\%s -s 字符串\n例如:%s -s 浏阳\n", argv[0], argv[0]);
        puts("----------------------------------------");
        exit(1);
    //搜索ip记录
    }elseif(argc==2){
        puts(argv[1]);
        charstring[255]="";
        unsigned longll = seekIpBinarySearch(argv[1]);//二分法搜索ip记录位置
        seekCountryArea(string, ll);//从ll位置读取ip记录信息
        puts(string);
    }elseif(argc == 3 ){
        //导出记录
        if(strcmp(argv[1],"-o")==0){
            puts("准备导出");
            //文件已经存在(,还需要判断是否可写,不然崩溃)
            if(access(argv[2],F_OK) == 0){
               printf("是否覆盖%s(Y/N)",argv[2]);
               charch = 0;
               while( (ch = tolower(getchar())) != 'y'&& ch !='n') {
                   printf("是否覆盖%s(Y/N)",argv[2]);
               }
               if(ch =='n')
                   exit(1);
            }
            exportData(argv[2]);
        }elseif(strcmp(argv[1],"-s")==0){
            searchIpByName(argv[2]);
        }else{
            puts("有任何问题请联系:hehuiahui@163.com");
        }
    //其他
    }else{
        puts("有任何问题请联系:hehuiahui@163.com");
    }
}
 
/**
 * 从当前位置读取4个字节转换为ip字符串
 * @param char *string 保存ip字符串
 */
voidreadIpString(char*string)
{
// if(sizeof(string) < 16)
//     realloc(string, 16);
sprintf(string, "%d.%d.%d.%d", fgetc(ipFile), fgetc(ipFile), fgetc(ipFile), fgetc(ipFile));
//  free(string);
}
 
/**
 * 导出记录
 * @param char *filename 文件名
 *
 */
voidexportData(char*fileName)
{
    FILE*fp = fopen(fileName, "wb");
    unsigned longi=0;
    unsigned longdata[1]={0};
    charstring[255]="";
    unsigned longdi = (ipSum/100);
    intj=0;
    while(!feof(ipFile) && i != ipSum){
        //起始ip
        fseek(ipFile, ipBegin + RECORD_LENGTH * i, SEEK_SET);
        readIpString(string);
        fprintf(fp, "%-16s", string);
        //结束ip
        fread(data, 1, 3, ipFile);
        fseek(ipFile, data[0], SEEK_SET);
        readIpString(string);
        fprintf(fp, "%-16s", string);
        //国家地区
        seekCountryArea(string, data[0]);
        fputs(string, fp);
        fputs("\r\n",fp); // \r\n for windows
        //导出进度
        if(i%di==0){
            if(j>9)
                putchar('\b');
            putchar('\b');
            putchar('\b');
            if(j%2==0)
                putchar('#');
            printf("%d%%",j++);
        }
        ++i;
    }
    puts("\n导出完毕");
}
 
/**
 * 搜索国家地区中包含某字符串的ip段
 * @param char *name 要搜索的字符串
 */
voidsearchIpByName(char*name)
{
    unsigned longi=0;
    unsigned longdata[1]={0};
    charstring[255]="";
    unsigned longj=0;
    intk=0;
    while(!feof(ipFile) && i != ipSum){
 
        fseek(ipFile, ipBegin + RECORD_LENGTH * i +4, SEEK_SET);
        fread(data, 1, 3, ipFile);
        seekCountryArea(string, data[0]);
        if(strstr(string, name) != NULL) {
            while(k>0){
                putchar('\b');
                --k;
            }
            charipStr[16]="";
            fseek(ipFile, ipBegin + RECORD_LENGTH * i, SEEK_SET);
            readIpString(ipStr);
            printf("%-16s", ipStr);
 
            fread(data, 1, 3, ipFile);
            fseek(ipFile, data[0], SEEK_SET);
            readIpString(ipStr);
            printf("%-16s", ipStr);
 
            puts(string);
            ++j;
        }else{
            //等待
             if(i%(ipSum/50)==0){
                 putchar('>');
                 ++k;
             }
        }
        ++i;
    }
 
    while(k>0){
        putchar('\b');
        --k;
    }
    printf("总共搜索到 %lu 条记录。                              ",j);
}
localIp.h
#ifndef LOCAL_IP_H
#define LOCAL_IP_H
 
intlocalIp(char*ip);
#endif
localIp.c
/**
 * 获取本机ip地址
 *
 * 需要指定wsock32.lib
 * gcc需要指定libwsock32.a
 * @author http://www.heui.org
 * @version 0.1
 */
 
#include <winsock2.h>
#include <wsipx.h>
//#include "wsnwlink.h"
#include <stdio.h>
 
#include "localIp.h"
 
intlocalIp(char*ip)
{
    ////////////////
    // Initialize windows sockets API. Ask for version 1.1
    //
    WORDwVersionRequested = MAKEWORD(1, 1);
    WSADATA wsaData;
    if(WSAStartup(wVersionRequested, &wsaData)) {
        printf("WSAStartup failed %s\n", WSAGetLastError());
        return-1;
    }
 
    //////////////////
    // Get host name.
    //
    charhostname[256];
    intres = gethostname(hostname, sizeof(hostname));
    if(res != 0) {
        printf("Error: %u\n", WSAGetLastError());
        return-1;
    }
 
    ////////////////
    // Get host info for hostname.
    //
    structhostent* pHostent = gethostbyname(hostname);
    if(pHostent==NULL) {
        printf("Error: %u\n", WSAGetLastError());
        return-1;
    }
 
    structsockaddr_in sa;
    intnAdapter;
    char*addr;
    for(nAdapter=0; pHostent->h_addr_list[nAdapter]; nAdapter++) {
        memcpy( &sa.sin_addr.s_addr, pHostent->h_addr_list[nAdapter],pHostent->h_length);
 
        addr =inet_ntoa(sa.sin_addr);
         // Output the machines IP Address.
      //  printf("Address: %s\n", addr =inet_ntoa(sa.sin_addr)); // display as string
    }
    memcpy(ip,addr,16);
    //////////////////
    // Terminate windows sockets API
    //
    WSACleanup();
    return0;
}
/*
int main()
{
 
    char ip[16];
    localIp(ip);
    printf("%s",ip);
    return 0;
}*/
resource.rc

A ICON "my_icon.ico"

代码打包下载:纯真ip数据库(QQWry.Dat)查询源代码C语言版 qqwry0.82

转载自:纯真ip数据库(QQWry.Dat)查询源代码C语言版

转载于:https://my.oschina.net/mickelfeng/blog/129924

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值