分类:
2008-10-13 16:50:13
//新格式. 请尊重原作者的劳动, 不要将IP数据库用于商业用途.
#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 是类似 61.147.225.* 的数据,返回的具体地址仍在 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 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 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 GetData(unsigned char* str, FILE* pFile, int max)
{
int i = 0;
while ( (*(str+i)=fgetc(pFile)) && (i<(max-2)) )
i++;
str[i] = 0;
}
void 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, "未知");
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, "未知");
return;
}
if ( buf[0] )
GetData(buf+1, pFile, 40);
strcat(content, (char*)buf);
return;
}