回 帖 发 新 帖 刷新版面

主题:[讨论]关于解析纯真IP数据库的问题

这个类目前只有通过用户输入IP,然后找到这个IP所在的位段的功能,但是有一个很奇怪的现象,那就是如果输入的IP 在"25.0.0.0"-"30.255.255.255"之间就会出错,其他的IP地址都能得到正确的结果,这个问题我想了三天了,一直没有头绪,请各位帮帮忙,看看是什么问题,谢谢!!!


[code=c]
//IPSeeker.h
#pragma once

class IPSeeker
{
private:
    CString unKnowCountry;
    CString unKnowArea;
    CString dbFileName;
    int IP_INDEX_LENGTH;
    int REDIRECT_MODE_1;
    int REDIRECT_MODE_2;
    unsigned long INDEX_FIRST_ONE;
    unsigned long INDEX_LAST_ONE;

    unsigned long Offset;

    CString StrEndIP;
    CString StrBeginIP;
    CString StrCountry;
    CString StrArea;

    CStdioFile dbFile;

private:
    void Init(void);
    void GetOffsetFromIP(wchar_t* wChar_tIP);
    //unsigned long GetValue(unsigned long StartPos, int Length);
public:
    CString GetHexIP(unsigned long IntIP);
    unsigned long GetIntIP(wchar_t* wChar_tIP);
    CString GetWideCharIP(unsigned long IntIP);
public:
    IPSeeker(void);
    IPSeeker(WCHAR *dbfilename);
    ~IPSeeker(void);


    CString GetVersion(void);
    CString GetCountryFromIP(wchar_t* wChar_tIP);
};



//IPSeeker.cpp
#include "StdAfx.h"
#include "IPSeeker.h"


IPSeeker::IPSeeker(void)
{
    this->dbFileName=L"QQWry.dat";
    Init();
}

IPSeeker::IPSeeker(WCHAR *dbfilename)
{
    this->dbFileName=dbfilename;
    Init();
}

IPSeeker::~IPSeeker(void)
{
    dbFile.Close();
}

void IPSeeker::Init(void)
{
    this->IP_INDEX_LENGTH=7;
    this->REDIRECT_MODE_1=1;
    this->REDIRECT_MODE_2=2;
    this->unKnowCountry=L"未知国家";
    this->unKnowArea=L"未知地区";
    this->Offset=0;
    dbFile.Open(this->dbFileName,CFile::modeRead);
    dbFile.Read(&this->INDEX_FIRST_ONE,4);
    dbFile.Read(&this->INDEX_LAST_ONE,4);
    dbFile.SeekToBegin();
}

CString IPSeeker::GetVersion(void)
{

    return L"";
}

CString IPSeeker::GetHexIP(unsigned long IntIP)
{
    wchar_t HexList[]={L'0',L'1',L'2',L'3',L'4',L'5',L'6',L'7',L'8',L'9',L'A',L'B',L'C',L'D',L'E',L'F'};

    CString Result=L"";
    while(IntIP>0)
    {
        Result=HexList[IntIP%16]+Result;
        IntIP/=16;
    }
    if(Result.GetLength()%2!=0)
    {
        Result=L'0'+Result;
    }

    return Result;
}

unsigned long IPSeeker::GetIntIP(wchar_t *wChar_tIP)
{
    CString strTemp=wChar_tIP;
    CString strIP=L"";
    unsigned long Result=0;
    int time=0;
    int oldPointPos=0;
    int newPointPos=0;
    for(int i=0;i<strTemp.GetLength();i++)
    {
        int variable=strTemp.Find(L".",i);
        if(variable!=-1)
        {
            time++;
            i=variable;
        }
        else
            break;
    }
    if(time!=3)
        return -1;

    oldPointPos=0;
    newPointPos=strTemp.Find(L".",oldPointPos);
    strIP=strTemp.Mid(oldPointPos,newPointPos);
    oldPointPos=newPointPos;
    int p=_wtoi(strIP.Mid(0).GetBuffer(strIP.Mid(0).GetLength()));
    if(p>=0 && p<=255)
        Result+=(p<<24);
    else
        return -1;

    newPointPos=strTemp.Find(L".",oldPointPos+1);
    strIP=strTemp.Mid(oldPointPos+1,newPointPos);
    oldPointPos=newPointPos;
    p=_wtoi(strIP.Mid(0).GetBuffer(strIP.Mid(0).GetLength()));
    if(p>=0 && p<=255)
        Result+=(p<<16);
    else
        return -1;

    newPointPos=strTemp.Find(L".",oldPointPos+1);
    strIP=strTemp.Mid(oldPointPos+1,newPointPos);
    oldPointPos=newPointPos;
    p=_wtoi(strIP.Mid(0).GetBuffer(strIP.Mid(0).GetLength()));
    if(p>=0 && p<=255)
        Result+=(p<<8);
    else
        return -1;

    strIP=strTemp.Mid(oldPointPos+1);
    p=_wtoi(strIP.Mid(0).GetBuffer(strIP.Mid(0).GetLength()));
    if(p>=0 && p<=255)
        Result+=p;
    else
        return -1;

    return Result;
}

CString IPSeeker::GetWideCharIP(unsigned long IntIP)
{
    CString strHexIP=this->GetHexIP(IntIP);
    CString Result=L"";
    CString strTemp=L"";
    CString strFormat=L"";
    if(strHexIP.GetLength()!=8)
        return L"";
    for(int i=0;i<8;i+=2)
    {
        strTemp=strHexIP.Mid(6-i,2);
        strFormat.Format(L"%u",wcstol(strTemp.GetBuffer(strTemp.GetLength()),0,16));
        Result=strFormat+L"."+Result;
    }
    return Result.Left(Result.GetLength()-1);
}


CString IPSeeker::GetCountryFromIP(wchar_t *wChar_tIP)
{
    CString Result=L"";
    this->GetOffsetFromIP(wChar_tIP);


    return Result;
}

void IPSeeker::GetOffsetFromIP(wchar_t *wChar_tIP)
{
    unsigned long UserIntIP=this->GetIntIP(wChar_tIP);
    unsigned long BeginIntIP=0;
    unsigned long EndIntIP=0;
    unsigned long Offset=0;

    int TotalRecord=(INDEX_LAST_ONE-INDEX_FIRST_ONE+7)/7+1;

    int IntUpper=TotalRecord;
    int IntLow=0;
    int IntInterspace=0;

    //在索引区中用二分法查找
    while(IntLow<=IntUpper)
    {
        IntInterspace=(IntUpper+IntLow)/2;
        dbFile.Seek(INDEX_FIRST_ONE+IntInterspace*7,CFile::begin);
        dbFile.Read(&BeginIntIP,4);
        if(UserIntIP<BeginIntIP)
        {
            IntUpper=IntInterspace-1;
        }
        else
        {
            dbFile.Seek(INDEX_FIRST_ONE+IntInterspace*7+4,CFile::begin);
            dbFile.Read(&Offset,3);
            dbFile.Seek(Offset,CFile::begin);
            dbFile.Read(&EndIntIP,4);
            if(UserIntIP>EndIntIP)
            {
                IntLow=IntInterspace+1;
            }
            else
            {
                break;
            }
        }
    }





    //开始IP
    this->StrBeginIP=this->GetWideCharIP(BeginIntIP);
    AfxMessageBox(L"开始IP:"+this->StrBeginIP);


    //结束IP
    this->StrEndIP=this->GetWideCharIP(EndIntIP);
    AfxMessageBox(L"结束IP:"+this->StrEndIP);

    this->Offset=Offset;
}

[/code]

回复列表 (共1个回复)

沙发

朋友搞的太复杂了点吧
Arry_Ip = Split(AccessIP,".")
ValueOfAccessIP = 0
For i=LBOUND(Arry_Ip) to UBOUND(Arry_Ip)
    IF i=0 Then
        ValueOfAccessIP = ValueOfAccessIP + Cint(Arry_Ip(i))*256*256*256
    End if
    IF i=1 Then
        ValueOfAccessIP = ValueOfAccessIP + Cint(Arry_Ip(i))*256*256
    End if
    IF i=2 Then
        ValueOfAccessIP = ValueOfAccessIP + Cint(Arry_Ip(i))*256
    End if
    IF i=3 Then
        ValueOfAccessIP = ValueOfAccessIP + Cint(Arry_Ip(i))
    End if  
Next
_______________________________________________________________________________________
这是我在ASP中用的部分代码,我想用上面的思路似乎要简单的多吧(先计算各段的区间值,并增加字段)

我来回复

您尚未登录,请登录后再回复。点此登录或注册