Python IP地址 socket.inet_ntoa unpack/pack
2017-09-20 00:10
190 查看
# -*- coding: utf-8 -*- __author__ = 'Jacky zhou' import socket,struct def test(): netIp = socket.inet_aton('255.255.255.0') intIp = struct.unpack("!I", netIp)[0] intIp2 = struct.unpack("I", netIp)[0] print(netIp,intIp, intIp2) socket.inet_ntoa(struct.pack("!I", intIp)) print(socket.inet_ntoa(struct.pack("I", intIp2))) hostIp = socket.ntohl(intIp) print(hostIp) # 打印如下信息: # b'\xff\xff\xff\x00' 4294967040 16777215 # 255.255.255.0 # 16777215 #此函数从’192.168.6.110’ 可以转换为数字’ 3232237166’,此数字为网络字节序 def Ip2Int(ip): import struct,socket return struct.unpack("!I",socket.inet_aton(ip))[0] #打印如下信息: # 3232237166 # 此函数从网络字节序的数字’’转换为ip def Int2Ip(i): import socket,struct return socket.inet_ntoa(struct.pack("!I",i)) # 打印如下信息: # 192.168.6.110 if __name__ == '__main__': # test() # print(Ip2Int("192.168.6.110")) # print(Int2Ip(3232237166)) >>> socket.ntohl(struct.unpack("I",socket.inet_aton('6.7.8.9'))[0]) 101124105 >>> socket.inet_ntoa(struct.pack('I',socket.htonl(101124105))) '6.7.8.9' >>> struct.unpack("I",socket.inet_aton('6.7.8.9')) (151521030,) >>> socket.ntohl(151521030) 101124105 >>> socket.htonl(101124105) 151521030 >>> struct.unpack('i',socket.inet_aton('6.7.8.9')) (151521030,) >>> struct.pack('i', 101124105) b'\t\x08\x07\x06' >>> struct.pack('i',151521030) b'\x06\x07\x08\t' >>> socket.inet_ntoa(struct.pack('I',socket.ntohl(101124105))) '6.7.8.9' >>> socket.htonl(struct.unpack("I",socket.inet_aton('6.7.8.9'))[0]) 101124105
(1). inet_aton 将ip地址的4段地址分别进行2进制转化,输出用16进制表示: 1.2.3.4 ——inet_aton——> 0000 0001,0000 0010,0000 0011,0000 0100 (2).unpack的处理是按16进制(4bit)将2进制字符,从后向前读入的,低位入,处理成: 00000100 00000011 00000010 00000001 也就是 4 3 2 1 pack也一样,从后向前读入字符,所以—— 用16进制表示的1 2 3 4(16909060)打包成 4 3 2 1 的顺序; 用16进制表示的4 3 2 1(67305985)打包成 1 2 3 4 的顺序; (3) ntohl, htonl 表示的是网络地址和主机地址之间的转换(network byte <==> host byte) 由于unpack/pack的解/打包的颠倒顺序,必须通过htonl 或者 ntohl 进行处理。 (4) network byte, host byte 这 2个名词折腾半天,host byte 由于处理器的方式不同 little-endian或者big-endian,将ip地址转换的最终输出是不一样的, big-endian: 最高位在左边(内存存储空间的最低位) little-endian: 最高位在右边(内存存储空间的最低位) 由于x86本身的处理属于little-endian,所以上述应该按照标准的network byte 进行处理,这样可避免cpu造成的不同: socket.htonl(struct.unpack("I",socket.inet_aton('1.2.3.4'))[0]) socket.inet_ntoa(struct.pack('I',socket.htonl(16909060))) ############################################################################### (1个64位amd+32位windows, 1个32位intel+linux, 出来的数值是一样的: />>> socket.ntohl(struct.unpack("I",socket.inet_aton('220.194.61.32'))[0]) -591250144 />>> socket.inet_ntoa(struct.pack('I',socket.htonl(-591250144))) '220.194.61.32' 但是64位amd+64位linux,是这样: />>> socket.ntohl(struct.unpack("I",socket.inet_aton('220.194.61.32'))[0]) 3703717152 />>> socket.inet_ntoa(struct.pack('I',socket.htonl(-591250144))) '220.194.61.32' />>> socket.inet_ntoa(struct.pack('I',socket.htonl(3703717152))) '220.194.61.32' unpack/pack和cpu,os无关; socket.ntohl/htonl的输出结果int型 对32 os,处理成signed 类型,首位1被处理成负数; 对 64位 os,则是unsigned类型; (5)mysql里面的函数是inet_aton, inet_ntoa 和python的socket不同,直接实现ip string到network byte的转换,python里面只能实现ip地址到network byte的2进制转换: mysql> select inet_aton('1.2.3.4'); -> 16909060 mysql> select inet_ntoa(16909060); -> 1.2.3.4
相关文章推荐
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack
- Python IP地址 socket.inet_ntoa unpack/pack