获取MAC地址
我需要一种在运行时确定计算机的MAC地址的跨平台方法。对于Windows,可以使用" wmi"模块,在Linux下,我能找到的唯一方法是运行ifconfig并在其输出中运行一个正则表达式。我不喜欢使用只能在一个OS上运行的程序包,并且更不用说容易出错的语法解析另一个程序的输出。
有谁知道跨平台方法(Windows和Linux)方法来获取MAC地址?如果没有,还有谁比我上面列出的方法更优雅?
解决方案
netifaces是一个很好的模块,可用于获取mac地址(和其他地址)。它是跨平台的,比使用套接字或者uuid更有意义。
>>> import netifaces >>> netifaces.interfaces() ['lo', 'eth0', 'tun2'] >>> netifaces.ifaddresses('eth0')[netifaces.AF_LINK] [{'addr': '08:00:27:50:f2:51', 'broadcast': 'ff:ff:ff:ff:ff:ff'}]
- pypi位置
- netifaces的良好入门
我不知道统一的方式,但是我们可能会发现以下有用的东西:
http://www.codeguru.com/Cpp/I-N/network/networkinformation/article.php/c5451
在这种情况下,我要做的就是将它们包装成一个函数,并根据操作系统运行适当的命令,根据需要进行解析,并仅返回所需格式的MAC地址。当然,除了我们只需要执行一次,并且与主代码相比,它看起来更干净以外,其他所有内容都是一样的。
Python 2.5包含一个uuid实现(至少在一个版本中),该实现需要mac地址。我们可以轻松地将mac查找功能导入我们自己的代码中:
from uuid import getnode as get_mac mac = get_mac()
返回值是作为48位整数的mac地址。
对于Linux,我们可以使用SIOCGIFHWADDR ioctl检索MAC地址。
struct ifreq ifr; uint8_t macaddr[6]; if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) return -1; strcpy(ifr.ifr_name, "eth0"); if (ioctl(s, SIOCGIFHWADDR, (void *)&ifr) == 0) { if (ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER) { memcpy(macaddr, ifr.ifr_hwaddr.sa_data, 6); return 0; ... etc ...
我们已将问题标记为" python"。我不知道要获取此信息的现有Python模块。我们可以使用ctypes直接调用ioctl。
请注意,我们可以使用条件导入在python中构建自己的跨平台库。例如
import platform if platform.system() == 'Linux': import LinuxMac mac_address = LinuxMac.get_mac_address() elif platform.system() == 'Windows': # etc
这将允许我们使用os.system调用或者特定于平台的库。
我们应该注意的另一件事是,uuid.getnode()
可以通过返回随机的48位数字来伪造MAC地址,这可能不是我们所期望的。同样,也没有明显的迹象表明MAC地址已被伪造,但是我们可以通过两次调用getnode()
并查看结果是否变化来检测到它。如果两个调用都返回相同的值,则说明我们具有MAC地址,否则得到的是伪造的地址。
>>> print uuid.getnode.__doc__ Get the hardware address as a 48-bit positive integer. The first time this runs, it may launch a separate program, which could be quite slow. If all attempts to obtain the hardware address fail, we choose a random 48-bit number with its eighth bit set to 1 as recommended in RFC 4122.