VC实现查找纯真数据库
纯真数据库的查找实现,VS2008编译,不知道有无兼容性问题.参考了<纯真IP数据库格式详解>这篇文章,很感谢作者,我使用的是作者建议的折半查找方法,代码这样写不知道够不够精简,因为作者给出的源码不知道是什么东东(作者说是Java,但好似有几个结构没写出来,糊涂~~),看到好晕所以自己写一个查找算法.(刚好我要用^.^)
我是先用CreateFile打开纯真数据库,然后CreateFileMapping+MapViewOfFile做一个内存映射文件,这样好方便操作.最后就是按照作者给的纯真数据库的存储结构来一步步找了.代码如下:
ULONG SearchIdxTargetOffer(LPVOID lpPoint, ULONG ulIp, ULONG pIdxFirstOffer, ULONG pIdxLastOffer)
{
ULONG pTargetOffer, ulnow, pIpArea;
ulnow = (pIdxLastOffer - pIdxFirstOffer) / 2;
ulnow -= ulnow % 7;
pIpArea = *(PULONG)((LPBYTE)lpPoint + pIdxFirstOffer + ulnow);
if(ulnow == 0)
{
if(ulIp >= *(PULONG)((LPBYTE)lpPoint + pIdxFirstOffer + 7))
pTargetOffer = *(PULONG)((LPBYTE)lpPoint + pIdxFirstOffer + 11);
else pTargetOffer = *(PULONG)((LPBYTE)lpPoint + pIdxFirstOffer + 4);
}
else if(ulIp > pIpArea)
{
pTargetOffer = SearchIdxTargetOffer(lpPoint, ulIp, pIdxFirstOffer + ulnow, pIdxLastOffer);
}
else if(ulIp < pIpArea)
{
pTargetOffer = SearchIdxTargetOffer(lpPoint, ulIp, pIdxFirstOffer, pIdxLastOffer - ulnow);
}
else if(ulIp == pIpArea)
{
pTargetOffer = *(PULONG)((LPBYTE)lpPoint + pIdxFirstOffer + ulnow + 4);
}
return (pTargetOffer << 8) >> 8;
}
void SearchSetInformation(LPBYTE pPointer, LPVOID pQQWryDatPointer,
LPTSTR lpContry, ULONG ulContryLenght,
LPTSTR lpAddress, ULONG ulAddressLenght)
#define OFFER(pOffer) ((*(PULONG)((LPBYTE)pOffer + 1) << 8) >> 8)
{
if(*pPointer == 0x01)
{
SearchSetInformation((LPBYTE)pQQWryDatPointer + OFFER(pPointer),
pQQWryDatPointer, lpContry, ulContryLenght, lpAddress, ulAddressLenght);
}
else if(*pPointer == 0x02)
{
wcscpy_s(lpContry, ulContryLenght, CA2W((LPSTR)pQQWryDatPointer + OFFER(pPointer)));
pPointer += 4;
if(*pPointer == 0x01 || *pPointer == 0x02)
wcscpy_s(lpAddress, ulAddressLenght, CA2W((LPSTR)pQQWryDatPointer + OFFER(pPointer)));
else wcscpy_s(lpAddress, ulAddressLenght, CA2W((LPSTR)pPointer));
}
else
{
wcscpy_s(lpContry, ulContryLenght, CA2W((LPSTR)pPointer));
pPointer += strlen((LPSTR)pPointer) + 1;
if(*pPointer == 0x01 || *pPointer == 0x02)
wcscpy_s(lpAddress, ulAddressLenght, CA2W((LPSTR)pQQWryDatPointer + OFFER(pPointer)));
else wcscpy_s(lpAddress, ulAddressLenght, CA2W((LPSTR)pPointer));
}
}
void SearchQQWryFromIPW(IN ULONG ulIp, OUT LPTSTR lpContry, IN ULONG ulContryLenght,
OUT LPTSTR lpAddress, IN ULONG ulAddressLenght)
{
HANDLE hFile = CreateFile(_T("QQWry.Dat"), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if(hFile)
{
HANDLE hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
if(hMapping)
{
LPVOID pQQWryDatPointer;
pQQWryDatPointer = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if(pQQWryDatPointer)
{
LPBYTE pip = (LPBYTE)&ulIp;
*pip = *pip ^ *(pip+3);
*(pip+3) = *pip ^ *(pip+3);
*pip = *pip ^ *(pip+3);
*(pip+1) = *(pip+1) ^ *(pip+2);
*(pip+2) = *(pip+1) ^ *(pip+2);
*(pip+1) = *(pip+1) ^ *(pip+2);
ULONG pContentsOffer = SearchIdxTargetOffer(pQQWryDatPointer, ulIp,
*(PULONG)pQQWryDatPointer, *(PULONG)((LPBYTE)pQQWryDatPointer + 4));
SearchSetInformation((LPBYTE)pQQWryDatPointer + pContentsOffer + 4,
pQQWryDatPointer, lpContry, ulContryLenght, lpAddress, ulAddressLenght);
}
UnmapViewOfFile(pQQWryDatPointer);
}
CloseHandle(hMapping);
}
CloseHandle(hFile);
}
以上代码在VS2008中编译通过,啊!忘记说,这里我写的是Unicode版本的,如果大家想用在VC6中那么要改一下就可以了.
VOID
SearchQQWryFromIP(
IN ULONG ulIP //将IP转换成ULONG
OUT LPTSTR ipContry //返回国家
IN ULONG ulContryLenght
OUT LPTSTR ipAddress //返回地区
IN ULONG ulAddressLenght
);