我需要在运行时间确定的计算机的MAC地址的跨平台的方法。 用于Windows的“WMI”模块,可以用来和Linux下的唯一方法我能找到的就是使用ifconfig运行和运行在其输出端的正则表达式。 我不喜欢用包,仅适用于一个操作系统,并解析另一个程序的输出似乎并不很优雅更不用说容易出错。
有谁知道一个跨平台的方法(Windows和Linux)方法来获得MAC地址? 如果没有,有没有人知道任何更优雅的方法,那么这些我上面列出?
我需要在运行时间确定的计算机的MAC地址的跨平台的方法。 用于Windows的“WMI”模块,可以用来和Linux下的唯一方法我能找到的就是使用ifconfig运行和运行在其输出端的正则表达式。 我不喜欢用包,仅适用于一个操作系统,并解析另一个程序的输出似乎并不很优雅更不用说容易出错。
有谁知道一个跨平台的方法(Windows和Linux)方法来获得MAC地址? 如果没有,有没有人知道任何更优雅的方法,那么这些我上面列出?
Python 2.5中包括一个UUID实现,其中(在至少一个版本)需要的MAC地址。 您可以导入Mac的发现功能,为自己的代码很容易:
from uuid import getnode as get_mac
mac = get_mac()
返回值是MAC地址作为48位整数。
在Linux下这个问题得到MAC特定本地接口的纯Python的解决方案,最初发布的vishnubob评论,并通过对本·麦基改善这个ActiveState的食谱
#!/usr/bin/python
import fcntl, socket, struct
def getHwAddr(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15]))
return ':'.join(['%02x' % ord(char) for char in info[18:24]])
print getHwAddr('eth0')
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
你应该注意的另一件事是, 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.
有时候,我们有一个以上的网络接口。
一个简单的方法,找出一个特定的接口的MAC地址是:
def getmac(interface):
try:
mac = open('/sys/class/net/'+interface+'/address').readline()
except:
mac = "00:00:00:00:00:00"
return mac[0:17]
调用该方法是简单
myMAC = getmac("wlan0")
使用从这里开始我的回答: https://stackoverflow.com/a/18031868/2362361
要知道这将是非常重要的,你要的MAC这IFACE以来许多可以存在(蓝牙,几个网卡等)。
这样做的工作,当你知道你需要的MAC为IFACE的IP,使用netifaces
(在PyPI中提供):
import netifaces as nif
def mac_for_ip(ip):
'Returns a list of MACs for interfaces that have given IP, returns None if not found'
for i in nif.interfaces():
addrs = nif.ifaddresses(i)
try:
if_mac = addrs[nif.AF_LINK][0]['addr']
if_ip = addrs[nif.AF_INET][0]['addr']
except IndexError, KeyError: #ignore ifaces that dont have MAC or IP
if_mac = if_ip = None
if if_ip == ip:
return if_mac
return None
测试:
>>> mac_for_ip('169.254.90.191')
'2c:41:38:0a:94:8b'
请注意,您可以建立使用条件的进口蟒蛇自己的跨平台库。 例如
import platform
if platform.system() == 'Linux':
import LinuxMac
mac_address = LinuxMac.get_mac_address()
elif platform.system() == 'Windows':
# etc
这将允许您使用使用os.system来电或特定于平台的库。
你可以用psutil它是跨平台的做到这一点:
import psutil
mac_addresses = []
nics = psutil.net_if_addrs()
nics.pop('lo') # remove loopback since it doesnt have a real mac address
for i in nics:
for j in nics[i]:
if j.family == 17: # AF_LINK
mac_addresses.append(j.address)
对于Linux让我介绍一个shell脚本,将显示的MAC地址,并允许对其进行更改(MAC嗅探)。
ifconfig eth0 | grep HWaddr |cut -dH -f2|cut -d\ -f2
00:26:6c:df:c3:95
切arguements可以dffer(我不是专家)尝试:
ifconfig etho | grep HWaddr
eth0 Link encap:Ethernet HWaddr 00:26:6c:df:c3:95
要改变MAC,我们可以这样做:
ifconfig eth0 down
ifconfig eth0 hw ether 00:80:48:BA:d1:30
ifconfig eth0 up
将改变MAC地址00:80:48:BA:D1:30(暂时,将在重新引导时还原到实际之一)。
跨平台getmac包将这项工作,如果你不介意的依赖关系。 它的工作原理与Python 2.7+和3.4+。 它会尝试许多不同的方法,直到得到一个地址或返回无。
from getmac import get_mac_address
eth_mac = get_mac_address(interface="eth0")
win_mac = get_mac_address(interface="Ethernet 3")
ip_mac = get_mac_address(ip="192.168.0.1")
ip6_mac = get_mac_address(ip6="::1")
host_mac = get_mac_address(hostname="localhost")
updated_mac = get_mac_address(ip="10.0.0.1", network_request=True)
免责声明:我是包的作者。
更新(2019年1月14日):包现在只支持Python 2.7+和3.4+。 如果你需要使用旧的Python(2.5,2.6,3.2,3.3)工作,你仍然可以使用软件包的旧版本。
我不知道一个统一的方式,但继承人的东西,你可能会发现有用:
http://www.codeguru.com/Cpp/IN/network/networkinformation/article.php/c5451
我会做在这种情况下,将这些包装成一个功能,并且基于OS它将运行正确的命令,解析的要求,并只返回MAC地址格式,只要你想。 它ofcourse都一样,除非你只需要做一次,它看起来与主代码更加清晰。
或者,
import uuid
mac_id=(':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff)
对于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模块来获取这些信息。 你可以使用ctypes的直接调用IOCTL。