Chinaunix首页 | 论坛 | 博客
  • 博客访问: 723933
  • 博文数量: 251
  • 博客积分: 10367
  • 博客等级: 上将
  • 技术积分: 2750
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-10 14:43
文章分类

全部博文(251)

文章存档

2009年(2)

2008年(86)

2007年(163)

分类: C/C++

2008-01-08 00:47:33

程序中用的数据为:QQwry.dat(要解压缩)

当然,要看懂这个程序,还需了解一下QQwry.dat的文件格式(附纯真IP数据库格式详解.pdf)

example:(北大天网)

[webg@bigpc ipfinder]$ ./ipfinder QQWry.Dat 162.105.146.120 162.105.203.21 162.105.129.12
162.105.146.120: 北京大学, 计算机系网络实验室
162.105.203.21: 北京大学, 计算机系
162.105.129.12: 北京大学, 计算中心

/*
 * IPFinder.h -- 这个工具主要用来读取天网格式的存储文件.
 *
 *    Created: devdoer
 *
 *    Created: Jan. 2006. version 0.1.0
 *        # A framework was given.
 *
 *
 */



#ifndef _IP_FINDER_H_
#define _IP_FINDER_H_

#ifdef __cplusplus
extern "C" {
#endif

#include<stdio.h>

/* entry in the ip datbase (QQwry.dat)*/
typedef struct ip_info
{
  char ip[16];
  char *country;
  char *area;
  char start_ip[16];
  char end_ip[16];
  char *mode;
} IP_INFO;


IP_INFO *get_ip_by_index(unsigned long index_addr, FILE *fp);
void print_iptable(FILE *fp);
unsigned long search_ip(char *ip_in, FILE *fp);

#ifdef __cplusplus
}
#endif

#endi

 

 

/**********************************************
 * IP Search client for QQWry.Dat *
 * by taopku@gmail.com *
 *********************************************/


//#include

//#include

//#include

#include <iostream>
#include <string>
#include "IPFinder.h"

/* function definitions */
unsigned long get_long_addr3(unsigned char *buf);
char* get_string_by_addr(long addr, FILE *fp);
char* get_area(unsigned char* buffer, FILE *fp);

/* implementation */
static unsigned long ip_str2dec(char *ip_in)
{
  char *ip = strdup(ip_in);
  unsigned long ip_dec = 0;

  char *p;
  int i;
  for(i=0; i<3; i++) {
    p = strrchr(ip, '.');
    ip_dec |= atoi(p+1) << (8*i);
    *p = '\0';
  }
  ip_dec |= atoi(ip) << (8*i);
  free(ip);
  return ip_dec;
}

/*
static unsigned long ip_arr2dec(char **ip_arr)
{
  unsigned long ip_dec = 0;
  int i;
  for(i=0; i<4; i++)
    {
      ip_dec |= atoi(ip_arr[i]) << (8*(3-i));
    }
  return ip_dec;
}
*/


static unsigned long ip_arr2dec_r(unsigned char *ip_arr)
{
  unsigned long ip_dec = 0;
  int i;
  for(i=0; i<4; i++)
    {
      ip_dec |= ip_arr[i] << (8*i);
    }
  return ip_dec;
}

unsigned long get_long_addr3(unsigned char *buf)
{
  unsigned long addr = 0;
  /* addr = buf[0] + buf[1]*256 + buf[2]*65536; */
  addr = buf[0] | buf[1] << 8 | buf[2] << 16;
  return addr;
}

char* get_string_by_addr(long addr, FILE *fp)
{
  unsigned char buffer[1024];
  fseek(fp, addr, SEEK_SET);
  fread(buffer, 1024, 1, fp);
  return strdup((char*)buffer);
}

IP_INFO *get_ip_by_index(unsigned long index_addr, FILE *fp)
{
  IP_INFO *ipinfo = (IP_INFO *)malloc(sizeof(IP_INFO));

  unsigned char ip[4];
  unsigned char addr[3];
  unsigned long record_addr = 0;

  fseek(fp, index_addr, SEEK_SET);
  fread(ip, 4, 1, fp);
  fread(addr, 3, 1, fp);
  record_addr = get_long_addr3(addr);
  sprintf(ipinfo->start_ip, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]);

  unsigned char buffer[1024];
  unsigned long country_addr;

  fseek(fp, record_addr, SEEK_SET);
  fread(ip, 4, 1, fp);
  fread(buffer, 1024, 1, fp);
  sprintf(ipinfo->end_ip, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]);

  if (buffer[0] == 1)
  {
     country_addr = get_long_addr3(buffer + 1);
     fseek(fp, country_addr, SEEK_SET);
     fread(buffer, 1024, 1, fp);

     if (buffer[0] == 2)
     {
         ipinfo->country = get_string_by_addr(get_long_addr3(buffer + 1), fp);
         ipinfo->area = get_area(buffer + 4, fp);
         ipinfo->mode = "1 + 2";
     }
     else
     {
         ipinfo->country = get_string_by_addr(country_addr, fp);
         ipinfo->area = get_area(buffer + strlen(ipinfo->country) + 1, fp);
         ipinfo->mode = "1 + D";
     }

  }
  else if (buffer[0] == 2)
  {
     ipinfo->country = get_string_by_addr(get_long_addr3(buffer + 1), fp);
     ipinfo->area = get_area(buffer + 4, fp);
     ipinfo->mode = "2 + D";

  }
  else
  {
     ipinfo->country = strdup((char*)buffer);
     ipinfo->area = get_area(buffer + strlen(ipinfo->country) + 1, fp);
     ipinfo->mode = "D + D";
  }
  return ipinfo;
}

char* get_area(unsigned char* buffer, FILE *fp)
{
  if (buffer[0] == 1 || buffer[0] == 2)
    {
      return get_string_by_addr(get_long_addr3(buffer + 1), fp);
    }
  else
    {
      return strdup((char*)buffer);
    }
}

void print_iptable(FILE *fp)
{
  unsigned long index_start, index_end;
  fseek(fp, 0, SEEK_SET);
  fread(&index_start, 4, 1, fp);
  fread(&index_end, 4, 1, fp);
  /* printf("%lu %lu\n", index_start, index_end); */

  unsigned long i;
  IP_INFO *ipinfo;

  for(i=index_start; i<=index_end; i+=7)
    {
      ipinfo = get_ip_by_index(i, fp);
      printf("%s - %s\n%s, %s\n", ipinfo->start_ip, ipinfo->end_ip, ipinfo->country, ipinfo->area);

      free(ipinfo);
    }
}

unsigned long search_ip(char *ip_in, FILE *fp)
{
  unsigned long index_start, index_end, lo, hi, i, ip_i, ip_dest;
  unsigned char ip_arr[4];

  fseek(fp, 0, SEEK_SET);
  fread(&index_start, 4, 1, fp);
  fread(&index_end, 4, 1, fp);

  lo = 0;
  hi = (index_end - index_start) / 7;
  ip_dest = ip_str2dec(ip_in);

  while(lo <= hi)
  {
     i = (lo + hi) / 2;

     fseek(fp, index_start + i * 7, SEEK_SET);
     fread(ip_arr, 4, 1, fp);
     ip_i = ip_arr2dec_r(ip_arr);
     if (ip_i == ip_dest)
         return index_start + i * 7;
     else if (ip_i < ip_dest)
         lo = i + 1;
     else
         hi = i - 1;
  }

  return index_start + hi * 7;
}

#ifdef _TEST
int main(int argc, char **argv)
{
    FILE *fp;
    int index = 0;
    IP_INFO *ipinfo = NULL;

    if (argc < 3)
    {
        printf("usage: %s path_to_QQWry.Dat ip_list\n", argv[0]);
        return -1;
    }

    fp = fopen(argv[1], "r");
    if (fp == NULL)
        return -1;

    /*print_iptable(fp);*/

    for (index = 0; index < argc-2; index++)
    {
        ipinfo = get_ip_by_index(search_ip(argv[index+2], fp), fp);
        printf("%s: %s, %s\n", argv[index+2], ipinfo->country, ipinfo->area);
        free(ipinfo);
    }

    fclose(fp);
    return EXIT_SUCCESS;
}
#endif

 

文件: QQWry.rar
大小: 2273KB
下载: 下载

               
文件: 纯真IP数据库格式详解.pdf
大小: 153KB
下载: 下载
阅读(1479) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

zhongku2008-06-16 14:45:16

非常感谢,我已经明白了.

zhongku2008-06-16 14:01:18

如果我要查找该ip属于哪个国家哪个城市,应该怎么做呢?

zhongku2008-06-16 14:00:04

请问作者,你的算法,可以查找该ip属于哪个城市吗 ?