最近做项目中涉及到ip的转换,做一小结;
1.c++中常用 到ip匹配 ,有时候给出来的是 127.0.0.1/32 等这样的格式,要想在处理的时候匹配,可以先转换格式。格式统一以后再进行匹配。
bool StringIpTonlpv4(std::string& strIp,uint32& nIp)
{
int nIp1 = 0, nIp2 = 0, nIp3 = 0, nIp4 = 0;
if (strIp.empty())
{
return false;
}
if ( sscanf(strIp.c_str(),"%d.%d.%d.%d",&nIp1,&nIp2,&nIp3,&nIp4) < 0 )
{
return false;
}
nIp = (nIp1<<24) + (nIp2<<16) + (nIp3<<8) + nIp4;
return true;
}
bool Ipv4ToStringIp( uint32 nIpv4,std::string & strIp)
{
char szBuffer[64];
if(nIpv4 <=0)
{
return false;
}
if(sprintf(szBuffer, "%u.%u.%u.%u", nIpv4 & 0xff, (nIpv4 >> 8) & 0xff, (nIpv4 >> 16) & 0xff, (nIpv4 >> 24) & 0xff) < 0)
{
return false;
}
strIp=std::string(szBuffer);
return true
}
2.mysql 中也经常用到 ip的转换
select inet_aton('127.0.0.1') as ip;
select inet_ntoa(2130706433) as ip;
3.python 中的ip转换
import socket
import struct
ip = '127.0.0.1'
int_ip = struct.unpack('!I', socket.inet_aton(ip))[0]
print(int_ip)
str_ip = socket.inet_ntoa(struct.pack('!I', int_ip))
print(str_ip)
大部分 项目中都是ip 去 匹配地址段。 那么实际中 我们把预先拿到的ip段转换位int 地址段。在通过二分查找的方法去匹配。
python 版
首先处理 预先 拿到的ip地址段:
def readIP(path):
templist=[]
try:
with open(path,'r',encoding='utf-8') as file:
for line in file:
tempdict={}
if "," in line:
line.replace("\n", "")
listInfo=line.split(",")
if "." in listInfo[2]:
#ip转换
BeginValueip = struct.unpack('!I', socket.inet_aton(listInfo[2]))[0]
EndValueip = struct.unpack('!I', socket.inet_aton(listInfo[3]))[0]
tempdict["beginValue"]= int(BeginValueip)
tempdict["endValue"]= int(EndValueip)
tempdict["desc"]= listInfo[0]
templist.append(tempdict)
except Exception as e:
print("readIP:%s" % e)
#对IP 地址 进行排序,因为有时间拿到的IP 并非顺序的
listInfoIP = sorted(templist,key = lambda e:e.__getitem__('beginValue'))
return listInfoIP
处理后是一个list的ip列表:
然后 在通过 二分查找去实现IP 匹配
def SearchValue(MatchList, nSearchValue):
nBeginIdx = 0
nEndIdx = len(MatchList)
desc=""
while nBeginIdx <= nEndIdx:
nMatchIdx = int(nBeginIdx+(nEndIdx -nBeginIdx)/ 2)
if nSearchValue >= MatchList[nMatchIdx]['beginValue'] and nSearchValue <= MatchList[nMatchIdx]['endValue']:
desc=MatchList[nMatchIdx]['desc']
break
elif nSearchValue > MatchList[nMatchIdx]['beginValue']:
if nBeginIdx == nMatchIdx:
break;
nBeginIdx = nMatchIdx
else:
if nEndIdx == nMatchIdx:
break;
nEndIdx = nMatchIdx;
return desc
在调用 IP 匹配前需要对IP地址的合法性 做判断:
def IsValidIp(strValue):
compile_ip=re.compile('^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
if compile_ip.match(strValue):
return True
else:
return False
利用正则表达式即可
C++ 版 原理一样。