Answers:
Python 2.5包含一个uuid实现(至少在一个版本中),该实现需要mac地址。您可以轻松地将mac查找功能导入您自己的代码中:
from uuid import getnode as get_mac
mac = get_mac()
返回值是作为48位整数的mac地址。
getnode
文档说它无法检测到mac,它将返回一个随机的long:按照RFC 4122中的建议设置为1。” 因此,请检查第八位!
hex(mac)
获得熟悉的mac十六进制格式
':'.join(("%012X" % mac)[i:i+2] for i in range(0, 12, 2))
对于大写MAC,每个字节之间用冒号分隔。
在Linux下针对此问题的纯python解决方案,用于获取特定本地接口的MAC,最初由vishnubob作为注释发布,并在本activestate食谱中由Ben 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')
这是Python 3兼容的代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import fcntl
import socket
import struct
def getHwAddr(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', bytes(ifname, 'utf-8')[:15]))
return ':'.join('%02x' % b for b in info[18:24])
def main():
print(getHwAddr('enp0s8'))
if __name__ == "__main__":
main()
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'}]
您应该注意的另一件事是,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,因为可能存在很多(蓝牙,几个nic等)。
当您知道需要使用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'
您可以使用跨平台的psutil进行此操作:
import psutil
nics = psutil.net_if_addrs()
print [j.address for j in nics[i] for i in nics if i!="lo" and j.family==17]
import socket
然后[addr.address for n in nics for addr in nics[n] if n == 'enp4s0' and addr.family == socket.AF_PACKET]
得到['ab:cd:ef:01:02:03']
如果您不介意依赖,则跨平台的getmac软件包将对此有效。它适用于Python 2.7+和3.4+。它将尝试许多不同的方法,直到获得地址或返回None。
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),则仍可以使用该软件包的旧版本。
要获取eth0
接口MAC地址,
import psutil
nics = psutil.net_if_addrs()['eth0']
for interface in nics:
if interface.family == 17:
print(interface.address)
我不知道统一的方式,但是以下内容可能对您有用:
http://www.codeguru.com/Cpp/IN/network/networkinformation/article.php/c5451
在这种情况下,我要做的就是将它们包装成一个函数,并根据操作系统运行适当的命令,根据需要进行解析,并仅返回所需格式的MAC地址。当然,除了您只需要执行一次,并且与主代码相比,它看起来更干净以外,其他所有内容都一样。
对于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(临时,重新启动后将还原为实际地址)。
或者,
import uuid
mac_id=(':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff)
For Linux you can retrieve the MAC address using a SIOCGIFHWADDR ioctl.
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 ...
You've tagged the question "python". I don't know of an existing Python module to get this information. You could use ctypes to call the ioctl directly.