実行時にコンピューターのMACアドレスを決定するクロスプラットフォームの方法が必要です。 Windowsの場合、「wmi」モジュールを使用できます。Linuxで見つけることができる唯一の方法は、ifconfigを実行し、その出力全体で正規表現を実行することでした。 1つのOSでのみ動作するパッケージを使用するのは好きではありません。また、別のプログラムの出力を解析することは、エラーが発生しやすいことは言うまでもありません。
誰もがMACアドレスを取得するためのクロスプラットフォームメソッド(WindowsおよびLinux)メソッドを知っていますか?そうでない場合、上記のリストよりもエレガントな方法を知っている人はいますか?
Python 2.5には、(少なくとも1つのバージョンで)MACアドレスが必要なuuid実装が含まれています。 Macの検索機能を独自のコードに簡単にインポートできます。
from uuid import getnode as get_mac
mac = get_mac()
戻り値は、48ビット整数としてのMACアドレスです。
Linuxでの特定のローカルインターフェイスのMACを取得するこの問題の純粋なpythonソリューション。元はvishnubobによるコメントとして投稿され、Ben Mackeyによる this activestate recipe
#!/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 __== "__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'}]
注意すべきもう1つの点は、uuid.getnode()
が、予期しない48ビットの乱数を返すことでMACアドレスを偽造できることです。また、MACアドレスが偽造されていることを示す明示的な表示はありませんが、getnode()
を2回呼び出して結果が変化するかどうかを確認することで検出できます。両方の呼び出しで同じ値が返された場合、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アドレス(Bluetooth、複数のNICなど)が存在する可能性があるため、MACが必要なifaceを知ることが重要です。
これは、netifaces
(PyPIで利用可能)を使用して、MACを必要とするifaceのIPを知っているときに仕事をします:
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
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)
条件付きインポートを使用して、pythonで独自のクロスプラットフォームライブラリを構築できることに注意してください。例えば.
import platform
if platform.system() == 'Linux':
import LinuxMac
mac_address = LinuxMac.get_mac_address()
Elif platform.system() == 'Windows':
# etc
これにより、os.system呼び出しまたはプラットフォーム固有のライブラリを使用できます。
依存関係を気にしないのであれば、クロスプラットフォームの 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)を使用する必要がある場合は、引き続き古いバージョンのパッケージを使用できます。
Linuxの場合、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)
私は統一された方法を知りませんが、ここにあなたが役に立つと思うかもしれない何かがあります:
http://www.codeguru.com/Cpp/I-N/network/networkinformation/article.php/c5451
この場合、私はこれらを関数にラップし、OSに基づいて適切なコマンドを実行し、必要に応じて解析し、必要に応じてフォーマットされたMACアドレスのみを返します。もちろん、同じことを1回行うだけでよく、メインコードからはすっきりしています。