C语言解析17monipdb.dat(http://www.ipip.net/)免费数据库

时间:2023-03-10 05:58:41
C语言解析17monipdb.dat(http://www.ipip.net/)免费数据库

官方给的链接打不开,而且里面的逻辑,每次都会打开文件,所以自己做了点个修改,发上来,借大家参考:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h> class IP17MON {
public:
static bool init(const std::string strPathToDataFile = "./17monipdb.dat") {
if(is_init) {
return true;
} printf("Opening %s\n", strPathToDataFile.c_str());
std::ifstream ifDataFile(strPathToDataFile.c_str(), std::ios::binary);
if (ifDataFile.is_open() == false) {
printf("%m\n");
return false;
}
// std vector reserve
vecDataFile.assign(std::istreambuf_iterator<char>(ifDataFile), std::istreambuf_iterator<char>());
printf("Load %lu bytes success\n", vecDataFile.size()); unsigned int uiIndexLen = 0;
memcpy(&uiIndexLen, &vecDataFile[0], 4);
uiIndexLen = ntohl(uiIndexLen);
printf("uiIndexLen = %d\n", uiIndexLen);
pIPIndex = &vecDataFile[4];
pIPData = &vecDataFile[uiIndexLen];
is_init = 1;
return true;
} static std::string find(const std::string strIP) {
struct sockaddr_in stSockAddrInet; memset(&stSockAddrInet, 0, sizeof(struct sockaddr_in));
if(inet_aton(strIP.c_str(), &stSockAddrInet.sin_addr) == 0) {
printf("convert error\n");
return "";
}
unsigned int uiIP = ntohl(stSockAddrInet.sin_addr.s_addr); // atoi The string can contain additional characters after those
// that form the integral number, which are ignored and have no
// effect on the behavior of this function.
int iFirst = atoi(strIP.c_str());
int iStart = 0;
memcpy(&iStart, pIPIndex+(iFirst*4), 4);
printf("iStart = %d\n", iStart);
int iMaxComLen = pIPData - pIPIndex - 1024 - 4; int iIndexOffset = -1;
unsigned char ucIndexLength = 0;
for (iStart = iStart * 8 + 1024; iStart < iMaxComLen; iStart += 8) {
unsigned int uiCurrIP = 0;
memcpy(&uiCurrIP, pIPIndex+iStart, 4);
uiCurrIP = ntohl(uiCurrIP);
if (uiCurrIP >= uiIP) {
iIndexOffset = 0;
memcpy(&iIndexOffset, pIPIndex+iStart+4, 3);
memcpy(&ucIndexLength, pIPIndex+iStart+7, 1);
break;
}
} if (iIndexOffset == -1) {
return "";
} std::string strRegion(pIPData + iIndexOffset - 1024, ucIndexLength);
return strRegion;
}
public:
static std::vector<char> vecDataFile;
static char *pIPIndex, *pIPData;
static int is_init;
};
char *IP17MON::pIPIndex;
char *IP17MON::pIPData;
int IP17MON::is_init = 0;
std::vector<char> IP17MON::vecDataFile; extern "C" const char *find_monip(const char *ip)
{
if (IP17MON::init() == false) {
return "";
}
return IP17MON::find(ip).c_str();
}