当前位置:Gxlcms > 数据库问题 > C语言解析17monipdb.dat(http://www.ipip.net/)免费数据库

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

时间:2021-07-01 10:21:17 帮助过:3人阅读

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

#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();    
}

  

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

标签:

人气教程排行