#include "cipaddressex.h"
#include "cipaddressex.h"
#include <QDebug>
#include <string.h>
#pragma warning(disable:4267)
#define EMPTY_STRING _T("")
#define UNKNOW_STRING "未知"
#define MODE1 0x01
#define MODE2 0x02
CIpAddressEx::CIpAddressEx(const IP& ip) : m_pFile(NULL),m_nStartIndex(0),m_nEndIndex(0)
{
m_Ip = ip;
GetInformation();
}
CIpAddressEx::~CIpAddressEx(void)
{
if (m_pFile && m_pFile->IsValid())
{
m_pFile->Close();
delete m_pFile;
m_pFile = NULL;
}
}
void CIpAddressEx::GetInformation()
{
if ( OpenFile() )
{
unsigned int uIpRecordOffset = SearchIp();
if (uIpRecordOffset)
{
if (MODE1 == GetValueByBytes(uIpRecordOffset + 4,1))
{
unsigned int uSecondOffset = GetValueByBytes(uIpRecordOffset+5,3);
if (MODE2 == GetValueByBytes(uSecondOffset,1))
{
unsigned int uCountryLastOffset = GetValueByBytes(uSecondOffset+1,3);
ExtractCountryValue(uCountryLastOffset);
unsigned int uAreaMode = GetValueByBytes(uSecondOffset+4,1);
if (MODE1 == uAreaMode || MODE2 == uAreaMode)
{
unsigned int uAreaLastOffset = GetValueByBytes(uSecondOffset+5,3);
ExtractAreaValue(uAreaLastOffset);
}
else
{
ExtractAreaValue(uSecondOffset+4);
}
}
else
{
int nCountryLength = ExtractCountryValue(uSecondOffset);
if (MODE1 == GetValueByBytes(nCountryLength + 1 + uSecondOffset,1) ||
MODE2 == GetValueByBytes(nCountryLength + 1 + uSecondOffset,1))
{
ExtractAreaValue(GetValueByBytes(nCountryLength + 1 + uSecondOffset + 1,3));
}
else
{
ExtractAreaValue(nCountryLength + 1 + uSecondOffset);
}
}
}
else if (MODE2 == GetValueByBytes(uIpRecordOffset + 4,1))
{
unsigned int uCountryOffset = GetValueByBytes(uIpRecordOffset + 5,3 );
ExtractCountryValue(uCountryOffset);
ExtractAreaValue(uIpRecordOffset + 8);
}
else
{
int nCountryLength = ExtractCountryValue(uIpRecordOffset+4);
ExtractAreaValue(nCountryLength + 1 + uIpRecordOffset + 4);
}
}
if (m_pFile && m_pFile->IsValid())
{
m_pFile->Close();
delete m_pFile;
m_pFile = NULL;
}
}
}
const std::string& CIpAddressEx::GetIpCountry()
{
return m_strIpCountry;
}
const std::string& CIpAddressEx::GetIpArea()
{
return m_strIpArea;
}
unsigned int CIpAddressEx::GetValueByBytes(unsigned int uStart,int nLength)
{
unsigned int *multiVal = (unsigned int*)malloc(nLength * sizeof(unsigned int));
unsigned char *pBuf = (unsigned char*)malloc(nLength * sizeof(unsigned char));
unsigned int uResult = 0;
//初始化数组
memset(pBuf,0,nLength * sizeof(unsigned char));
if (m_pFile && nLength < 5)
{
m_pFile->Seek(uStart,CLocalFile::begin);
for (int i = 0;i < nLength;i++)
{
m_pFile->Read((char*)pBuf,1);
multiVal[i] = (char)*pBuf & 0x000000FF;
pBuf++;
}
pBuf -= nLength;
for (int i = nLength-1;i >= 0;i--)
{
uResult = uResult * 0x100 + multiVal[i];
}
}
free(multiVal);
free(pBuf);
return uResult;
}
unsigned int CIpAddressEx::ConstructIp()
{
unsigned int valArr[4];
valArr[0] = 0x000000FF & m_Ip.bFirst;
valArr[1] = 0x000000FF & m_Ip.bSecond;
valArr[2] = 0x000000FF & m_Ip.bThird;
valArr[3] = 0x000000FF & m_Ip.bFourth;
unsigned int uResult = 0;
for (int i = 0;i < 4;i++)
{
uResult = uResult * 0x100 + valArr[i];
}
return uResult;
}
unsigned int CIpAddressEx::SearchIp()
{
unsigned int uIpAddress = ConstructIp();
unsigned int uCurrentRecord = 0;
unsigned int uTopIndex = m_nStartIndex,uBottomIndex = m_nEndIndex;
unsigned int uCurrentIndex = (( uBottomIndex - uTopIndex) / 7 / 2) * 7 + uTopIndex;
//二分查找
do
{
uCurrentRecord = GetValueByBytes(uCurrentIndex,4);
if ( uCurrentRecord > uIpAddress )
{
uBottomIndex = uCurrentIndex;
uCurrentIndex = (( uBottomIndex - uTopIndex) / 7 / 2) * 7 + uTopIndex;
}
else
{
uTopIndex = uCurrentIndex;
uCurrentIndex = (( uBottomIndex - uTopIndex) / 7 / 2) * 7 + uTopIndex;
}
} while ( uBottomIndex > uTopIndex + 7);
//返回结果
return GetValueByBytes(uCurrentIndex+4,3);
}
bool CIpAddressEx::OpenFile()
{
if (!m_pFile)
{
m_pFile = new CLocalFile(QQ_WRY, CLocalFile::modeRead | CLocalFile::typeBinary);
if (!m_pFile->IsValid())
{
delete m_pFile;
m_pFile = NULL;
qDebug()<<"无法打开文件,请检查文件路径是否正确";
return false;
}
}
m_pFile->SeekToBegin();
if (m_pFile->IsValid())
{
if (4 == m_pFile->Read((char*)&m_nStartIndex,4) &&
4 == m_pFile->Read((char*)&m_nEndIndex,4))
{
return true;
}
}
m_pFile->Close();
delete m_pFile;
m_pFile = NULL;
return false;
}
std::string CIpAddressEx::ExtractString(unsigned int uOffset)
{
std::string strResult;
if (m_pFile)
{
m_pFile->Seek(uOffset,CLocalFile::begin);
char pCountry[MAX_PATH];
char *pCountryReader = (char*)pCountry;
memset(pCountry,0,MAX_PATH * sizeof(char));
do
{
m_pFile->Read(pCountryReader,1);
pCountryReader++;
} while (pCountryReader - pCountry < MAX_PATH && pCountry[ pCountryReader - pCountry-1] != 0 );
strResult = pCountry;
}
return strResult;
}
int CIpAddressEx::ExtractAreaValue(unsigned int uOffset)
{
m_strIpArea = ExtractString(uOffset);
int nLength = m_strIpArea.length();
if (m_strIpArea.empty())
{
m_strIpArea = UNKNOW_STRING;
}
return nLength;
}
int CIpAddressEx::ExtractCountryValue(unsigned int uOffset)
{
m_strIpCountry = ExtractString(uOffset);
int nLength = m_strIpCountry.length();
if (m_strIpCountry.empty())
{
m_strIpCountry = UNKNOW_STRING;
}
return nLength;
}
C++ 获取ip地址归属地,终端设备地理位置
需积分: 5 48 浏览量
2023-05-09
11:49:04
上传
评论
收藏 5.18MB ZIP 举报
Amos—vrv
- 粉丝: 0
- 资源: 7
最新资源
- 基于matlab实现用有限元法计算电磁场的Matlab工具 .rar
- 基于matlab实现有限元算法 计算电磁场问题 边界条件包括第一类边界和第二类边界.rar
- 基于matlab实现用于计算不同车重下的电动汽车动力性和经济性.rar
- 基于matlab实现遗传算法求解多车场车辆路径问题 有多组算例可以用.rar
- 浏览器.apk
- 基于matlab实现是一个matlab中的power system 中搭建的一个模型
- 基于JSP毕业设计-教学管理系统(源代码+论文).zip
- 基于JSP毕业设计-家政管理系统-毕业设计.zip
- 基于Python实现淘宝商品评论采集(含逆向)源代码
- 基于matlab实现多目标进化算法NSGAⅡ&Matlab讲解.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈