在Python中将IP地址字符串转换为二进制

15
作为更大的应用程序的一部分,我正在尝试将 IP 地址转换为二进制。这样做的目的是为了稍后计算 Wake on LAN 流量的广播地址。我假设有比我想的方法更高效的方法。我的想法是将 IP 地址按八位划分,必要时在每个八位前面添加 0,将每个八位转换为二进制,然后组合结果。我应该查看 netaddr、sockets 还是完全不同的东西?
示例: 从 192.168.1.1 到 11000000.10101000.00000001.00000001

你想将IPv4地址转换为整数表示吗?还是你想要转换成什么二进制表示形式? - Nate
1
从192.168.1.1到11000000.10101000.00000001.00000001 - pizzim13
这是一种非常不常见的表达IP地址的方式。我认为没有任何模块可以生成或消费该格式。 - Thomas Wouters
1
在我看来,你所考虑的方式非常好且足够高效。 - ktdrv
8个回答

9
你是否想到了以下这样的东西?
ip = '192.168.1.1'
print '.'.join([bin(int(x)+256)[3:] for x in ip.split('.')])

我同意其他人的观点,你应该避免将其转换为二进制表示以实现你想要的目标。


这正是我在寻找的,但是我并不完全理解它是如何工作的。我知道你是通过 '.' 来分割 IP 地址,然后通过 '.' 来连接结果,并将其从整数转换为二进制,但是这个“(x)+256)[3:] for x in”完全让我无法理解。你能指引我查找一下你正在做什么的方向吗? - pizzim13
@pizzim13:没有魔法。你很好地理解了它的工作原理。+256 在这里是为了始终拥有一个9位二进制数,然后轻松地删除数字前面的 0b1。 - kriss
@pizzim13:对于[... for x in ...]部分,请参考Python文档中的列表推导式 - kriss

9

您是否需要的是 socket.inet_aton() 函数?


3
看起来这个代码有效:bin(struct.unpack('!I', socket.inet_aton('192.168.1.1'))[0]) -> '0b11000000101010000000000100000001'。这段代码的作用是将IP地址 '192.168.1.1' 转换成二进制表示,并在前面添加 '0b' 前缀以表示它是一个二进制数。 - jfs

8

目的是为了后续计算Wake on LAN流量的广播地址

ipaddr(参见PEP 3144):

import ipaddr

print ipaddr.IPNetwork('192.168.1.1/24').broadcast
# -> 192.168.1.255

在Python 3.3中,ipaddress模块
#!/usr/bin/env python3
import ipaddress

print(ipaddress.IPv4Network('192.162.1.1/24', strict=False).broadcast_address)
# -> 192.168.1.255

为了完全匹配你问题中的示例:
# convert ip string to a binary number
print(bin(int(ipaddress.IPv4Address('192.168.1.1'))))
# -> 0b11000000101010000000000100000001

3

您可以使用字符串格式函数将数字转换为二进制。我设计了以下这个函数:

def ip2bin(ip):
    octets = map(int, ip.split('/')[0].split('.')) # '1.2.3.4'=>[1, 2, 3, 4]
    binary = '{0:08b}{1:08b}{2:08b}{3:08b}'.format(*octets)
    range = int(ip.split('/')[1]) if '/' in ip else None
    return binary[:range] if range else binary

这将返回一个二进制IP或IP范围,因此您可以使用它来测试IP是否在范围内:

>>> ip2bin('255.255.127.0')
'11111111111111110111111100000000'
>>> ip2bin('255.255.127.0/24')
'111111111111111101111111'
>>> ip2bin('255.255.127.123').startswith(ip2bin('255.255.127.0/24'))
True

正是我所需要的。非常感谢。 - f4d0

1

定义变量中的IP地址

ipadd = "10.10.20.20"

将列表中的IP地址转换

ip = ipadd.split(".")

现在将IP地址转换为二进制数字。
print ('{0:08b}.{1:08b}.{2:08b}. 
    {3:08b}'.format(int(ip[0]),int(ip[1]),int(ip[2]),int(ip[3])))

00001010.00001010.00010100.00010100

1

我应该看netaddr、sockets还是完全不同的东西?

对于现在任何人的提问,如果你想要做一些Python 3.3+内置的ipaddress模块不支持的事情,你应该使用netaddr。以下是以netaddr为例实现你想要的功能的方法:

>>> from netaddr import IPAddress
>>> ip = IPAddress('192.168.1.1')
>>> print(ip.bits())
11000000.10101000.00000001.00000001

1
IP = '192.168.1.1'

ip2bin =  ".".join(map(str,["{0:08b}".format(int(x)) for x in IP.split(".")]))
print(ip2bin)

output

11000000.10101000.00000001.00000001

0

ip = '192.168.1.1'

k=[" "]

对于每个以"."分隔的x in ip:

   a=(bin(int(x))[2:])
   k.append(a)    

print(".".join(list(k))[2:])


1
您的回答当前不清楚。请进行[编辑],添加更多细节以帮助他人了解该如何回答该问题。您可以在帮助中心中找到有关撰写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接