主题:[讨论]关于解析纯真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]
[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]