up有分。

解决方案 »

  1.   

    分析 QQWRY.DAT 的数据格式这个文件由 WRY 文件头,和数据体两部分组成我以前曾经花了一个晚上,不断调试,终于把这个文件的格式分析清楚了这是文件头的结构(我的研究结果的一部分代码)
    struct WryFileHEAD
    {
      BYTE Reserved1[4];
      UINT TotalNum;  // 记录总数
      WORD BeginPos;  // 记录数据开始的偏移量
      WORD RecordSize; // 每条记录的大小
      BYTE Reserved2[20];  char StartIp[16];
      WORD StartIpSize;
      BYTE Reserved3[14];  char EndIp[16];
      WORD EndIpSize;
      BYTE Reserved4[14];  char Country[16];
      WORD CountrySize;
      BYTE Reserved5[14];  char Local[16];
      WORD LocalSize;
      BYTE Reserved6[14];  char Thank[16];
      WORD ThankSize;
      BYTE Reserved7[14];
    };剩下的你自己去分析吧
      

  2.   

    #define BYTE3INT(X)  (    ( X[0] & 0x000000FF ) \
                          | ( ( X[1] & 0x000000FF ) <<  8 ) \
                          | ( ( X[2] & 0x000000FF ) << 16 )  )#define BYTE4INT(X)  (    ( X[0] & 0x000000FF ) \
                          | ( ( X[1] & 0x000000FF ) <<  8 ) \
                          | ( ( X[2] & 0x000000FF ) << 16 ) \
                          | ( ( X[3] & 0x000000FF ) << 24 )  )struct INDEXITEM 
    {
        unsigned char ip[4];
        unsigned char offset[3];
    };int LocalityFromIP2(CString& str)
    {
        //str 是类似 *.*.*.* 的数据,返回的具体地址仍在 str 中。两端没有空格。    int i = 0, j = str.GetLength(), k = 0, l, IP[4];
        const char* p = (LPCTSTR)str;
        FILE* ipfp = NULL;
        CString ipstr;
        
        for( i = 0; i < 4; i ++ )
            * ( IP + i ) = -1;
        i = j = k = 0;
        for( ; k < 3; k ++ )
        {
            i = str.Find( '.', j );
            if( i == -1 )
                break;
            ipstr = str.Mid( j, i - j );
            
            for( l = 0; l < i - j; l ++ )
                if (  ipstr[l] < '0' || ipstr[l] > '9' )
                    return -1;
                
                * ( IP + k ) = atoi((const char*)(LPCTSTR)ipstr);
                j = i + 1;
        }
        for( i = 0; i < 3; i ++ )
            if( * ( IP + i ) == -1 )
                return -1;
            * ( IP + 3 ) = 5;
            ipfp = fopen("qqwry.dat", "rb");
            if( ipfp == NULL )
                return -1;
            char pbuf[256] = {0};
            fseek(ipfp, 0, SEEK_SET);
    unsigned int indexHeadPos = 0;
    unsigned int indexTailPos = 0; struct INDEXITEM target;
    target.ip[0] = IP[3];
    target.ip[1] = IP[2];
    target.ip[2] = IP[1];
    target.ip[3] = IP[0]; fread(&indexHeadPos, sizeof(indexHeadPos), 1, ipfp);
    fread(&indexTailPos, sizeof(indexTailPos), 1, ipfp); int amount = (indexTailPos - indexHeadPos)/sizeof(struct INDEXITEM);
    struct INDEXITEM start = LookForIndexItem(&target, ipfp, indexHeadPos, amount); char result[255] = {0};
    RetrieveContent(&start, target.ip, ipfp, result);
    str = result;        fclose(ipfp);
            return 0;
    }struct INDEXITEM CConnectSocket::LookForIndexItem(struct INDEXITEM* const pAimItem, 
      FILE* pFile, 
      unsigned int indexBasePos, 
      unsigned int indexAmount )
    {
        struct INDEXITEM tmp;
        int i = 0;
        int j = indexAmount;
        int s = (int)sizeof(struct INDEXITEM);
        while ( i < j - 1 ) 
    {
            int k = (int) (i+j)/2;
            int offset = (int)( k * s );
            fseek(pFile, indexBasePos+offset, SEEK_SET);
            fread(&tmp, s, 1, pFile);
            int c = Compare( tmp.ip, pAimItem->ip );
            if ( c > 0 )
                j = k;
            else if ( c < 0 )
                i = k;
            else 
    {
                i = k;
                j = k;
            }
        }    fseek(pFile, indexBasePos+i*s, SEEK_SET);
        fread(&tmp, s, 1, pFile);
        return tmp;
    }int CConnectSocket::Compare(unsigned char pA[4], unsigned char pB[4])
    {
        unsigned int a = BYTE4INT(pA);
        unsigned int b = BYTE4INT(pB);    if ( a > b )
            return 1;
        else if ( a < b )
            return -1;
        else
            return 0;
    }void CConnectSocket::GetData(unsigned char* str, FILE* pFile, int max)
    {
        int i = 0;
        while ( (*(str+i)=fgetc(pFile)) && (i<(max-2)) )
            i++;
        str[i] = 0;
    }void CConnectSocket::RetrieveContent(struct INDEXITEM* const pIndexItem, 
     unsigned char ip[4],
     FILE* pFile, 
     char* content )
    {
        // to get the pos from the offset array
        long tmp = 0;
        unsigned char buf[80];    int pos = BYTE3INT(pIndexItem->offset);
        fseek(pFile, pos, SEEK_SET);
        fread(buf, 4, 1, pFile);
        if ( Compare(ip, buf) > 0 ) 
    {
            strcat(content, "未知");
            //printf("未知数据\n");
            return;
        }    // 获取资料
        fread(buf, 1, 1, pFile);
        if ( buf[0] == 0x01 ) 
    { // 国家地区均重复, 跳转至新地址
            fread(buf, 3, 1, pFile);
            pos = BYTE3INT(buf);
            fseek(pFile, pos, SEEK_SET);
            fread(buf, 1, 1, pFile);
        }    // 获取国家
        if ( buf[0] == 0x02 ) 
    {
            // 获取国家偏移
            fread(buf, 3, 1, pFile);
            // 保存地区信息
            tmp = ftell(pFile);
            pos = BYTE3INT(buf);
            fseek(pFile, pos, SEEK_SET);
            fread(buf, 1, 1, pFile);
        }
        if ( buf[0] == 0x01 || buf[0] == 0x02 ) 
    {
            strcat(content, "未知");
            //printf("There is something wrong....\n");
            return;
        }    if ( buf[0] )
            GetData(buf+1, pFile, 40);
        strcat(content, (char*)buf);
        //printf("%s\t", buf);    // 获取地区
        if ( tmp )
            fseek(pFile, tmp, SEEK_SET);
        fread(buf, 1, 1, pFile);
        while ( buf[0] == 0x02 ) 
    {
            // 获取地区偏移
            fread(buf, 3, 1, pFile);
            pos = BYTE3INT(buf);
            fseek(pFile, pos, SEEK_SET);
            fread(buf, 1, 1, pFile);
        }
        if ( buf[0] == 0x01 || buf[0] == 0x02 ) 
    {
            strcat(content, "未知");
            //printf("There is something wrong....\n");
            return;
        }
        if ( buf[0] )
            GetData(buf+1, pFile, 40);
       // strcat(content,"        ");
        strcat(content, (char*)buf);    return;
    }