获取MAC地址

我需要在运行时确定计算机MAC地址的跨平台方法。 对于Windows,可以使用'wmi'模块,在Linux下我可以find的唯一方法是运行ifconfig并在其输出上运行正则expression式。 我不喜欢使用只适用于一个操作系统的软件包,parsing另一个程序的输出似乎不是很优雅,更不用说容易出错。

有谁知道一个跨平台的方法(Windows和Linux)的方法来获取MAC地址? 如果没有,那么有没有人知道我上面列出的更优雅的方法?

Python 2.5包含一个uuid实现(至less在一个版本中)需要mac地址。 您可以轻松地将mac查找function导入您自己的代码中:

from uuid import getnode as get_mac mac = get_mac() 

返回值是MAC地址48位整数。

纯粹的Python解决scheme,这个问题在Linux下得到一个特定的本地接口的MAC,最初由vishnubob发表评论,并在本Mackey在这个活跃的状态配方

 #!/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. 

有时我们有多个networking接口。

找出特定接口的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

因为许多可以存在的(蓝牙,几个nics等等),知道你想要MAC的时候是很重要的。

当你知道你需要MAC的iface的IP时,你可以使用netifaces (在PyPI中可用)来完成netifaces

 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 

testing:

 >>> mac_for_ip('169.254.90.191') '2c:41:38:0a:94:8b' 

请注意,您可以使用条件导入在Python中构build自己的跨平台库。 例如

 import platform if platform.system() == 'Linux': import LinuxMac mac_address = LinuxMac.get_mac_address() elif platform.system() == 'Windows': # etc 

这将允许您使用os.system调用或特定于平台的库。

对于Linux,让我介绍一个shell脚本,它将显示MAC地址并允许更改(MAC嗅探)。

  ifconfig eth0 | grep HWaddr |cut -dH -f2|cut -d\ -f2 00:26:6c:df:c3:95 

削减的争论可能会(我不是专家)尝试:

 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(暂时将在重新启动后恢复到实际的地址)。

我不知道统一的方式,但是可能会发现有用的东西:

http://www.codeguru.com/Cpp/IN/network/networkinformation/article.php/c5451

在这种情况下,我会做的是将它们包装成一个函数,并根据操作系统来运行正确的命令,根据需要进行parsing,并只返回格式化的MAC地址。 它的情况完全相同,只是你只需要做一次,而且从主代码看起来更干净。

你可以用跨平台的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解决scheme

 INTERFACE_NAME = "eth0" ####################################### def get_mac_id(ifname=INTERFACE_NAME): import commands words = commands.getoutput("ifconfig " + ifname).split() if "HWaddr" in words: return words[ words.index("HWaddr") + 1 ] else: return 'No MAC Address Found!' 

用法:

 print get_mac_id(ifname="eth0") 

对于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。