मैक एड्रेस प्राप्त करना


111

मुझे रन टाइम में कंप्यूटर के मैक पते को निर्धारित करने के लिए एक क्रॉस प्लेटफॉर्म विधि की आवश्यकता है। विंडोज़ के लिए 'wmi' मॉड्यूल का उपयोग किया जा सकता है और लिनक्स के तहत एकमात्र विधि जो मुझे मिल सकती है वह ifconfig को चलाने और इसके आउटपुट में एक रेगेक्स चलाने के लिए थी। मुझे एक पैकेज का उपयोग करना पसंद नहीं है जो केवल एक ओएस पर काम करता है, और दूसरे प्रोग्राम के आउटपुट को पार्स करना बहुत ही सुरुचिपूर्ण नहीं लगता है त्रुटि त्रुटि का उल्लेख नहीं करना।

क्या कोई मैक पता प्राप्त करने के लिए एक क्रॉस प्लेटफ़ॉर्म विधि (विंडोज़ और लिनक्स) विधि जानता है? यदि नहीं, तो क्या किसी को और अधिक सुरुचिपूर्ण तरीके पता हैं, जिन्हें मैंने ऊपर सूचीबद्ध किया है?


जवाबों:


160

पायथन 2.5 में एक यूयूआईडी कार्यान्वयन शामिल है जो (कम से कम एक संस्करण में) मैक पते की आवश्यकता है। आप आसानी से अपने खुद के कोड में मैक खोज समारोह आयात कर सकते हैं:

from uuid import getnode as get_mac
mac = get_mac()

रिटर्न मान 48 बिट पूर्णांक के रूप में मैक एड्रेस है।


25
मैंने बस एक विंडोज बॉक्स पर यह कोशिश की और यह बहुत अच्छा काम करता है ... सिवाय इसके कि मैंने जिस लैपटॉप पर कोशिश की, उसमें 2 एनआईसी (एक वायरलेस) है और यह निर्धारित करने का कोई तरीका नहीं है कि यह किस मैक पर लौटा। यदि आप इस कोड का उपयोग करना चाहते हैं तो चेतावनी का एक शब्द।
टेक्नोमलाजिकल ऑक्ट

24
बस एक चेतावनी: यदि आप getnodeदस्तावेज़ीकरण को देखते हैं तो यह कहता है कि यह मैक का पता लगाने में विफल होने पर एक यादृच्छिक लंबी लौटेगा: "यदि हार्डवेयर पता प्राप्त करने के सभी प्रयास विफल हो जाते हैं, तो हम अपने आठवें बिट के साथ एक यादृच्छिक 48-बिट संख्या चुनते हैं। RFC 4122 में अनुशंसित 1 के अनुसार। " तो उस आठवें बिट की जांच करें!
डेनिओनचसौर

27
hex(mac)मैक के परिचित हेक्स प्रारूप को प्राप्त करने के लिए
स्क्रीनशॉट 3

43
या ':'.join(("%012X" % mac)[i:i+2] for i in range(0, 12, 2))एक बृहदान्त्र मैक के लिए प्रत्येक बाइट के साथ एक बृहदान्त्र द्वारा अलग किया जाता है।
टॉमोलॉजिकल

5
getnode () कुछ अलग करता है हर बार जब मैं अपनी विंडोज़ 7 लैपटॉप को पुनरारंभ करता हूं।
नू एवरेस्ट

80

लिनक्स के तहत इस समस्या के लिए शुद्ध अजगर समाधान एक विशिष्ट स्थानीय इंटरफ़ेस के लिए मैक प्राप्त करने के लिए, मूल रूप से vishnubob द्वारा एक टिप्पणी के रूप में पोस्ट किया गया और इस सक्रिय नुस्खा में बेन मैके द्वारा सुधार किया गया

#!/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')

यह पायथन 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()

35

netifaces मैक एड्रेस (और अन्य एड्रेस) प्राप्त करने के लिए उपयोग करने के लिए एक अच्छा मॉड्यूल है। यह क्रोसप्लेट रिकॉर्डर है और सॉकेट या 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'}]


व्यक्तिगत रूप से इसका उपयोग किया जाता है, प्रत्येक सिस्टम पर एक विशिष्ट इंस्टॉल / संकलन की आवश्यकता होती है, लेकिन अच्छी तरह से काम करता है।
बजे

22

एक और बात जो आपको ध्यान देनी चाहिए, वह है कि uuid.getnode()एक अतिरिक्त 48-बिट संख्या को वापस करके मैक एड्र को नकली कर सकते हैं जो कि आप जो अपेक्षा कर रहे हैं वह नहीं हो सकता है। इसके अलावा, इसका कोई स्पष्ट संकेत नहीं है कि मैक एड्रेस को फेक कर दिया गया है, लेकिन आप इसे getnode()दो बार कॉल करके पता कर सकते हैं कि क्या परिणाम बदलता है। यदि दोनों कॉल द्वारा समान मान लौटाया जाता है, तो आपके पास मैक एड्रेस है, अन्यथा आपको एक फेक एड्रेस मिल रहा है।

>>> 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.

8
ऐसा नहीं है कि 8 वीं का मान 1 ठीक है क्योंकि इसका उपयोग नेटवर्क कार्ड द्वारा नहीं किया जा सकता है। बस यह जाँचने के लिए कि पता फेक है या नहीं, यह जाँचने के लिए पर्याप्त है।
Frédéric Grosshans

15
चेक सिर्फ इसके साथ किया जाता है: अगर (मैक >> 40)% 2: OSError बढ़ाएं, "सिस्टम के पास वैध मैक नहीं लगता है"
Frédéric Grosshans

17

कभी-कभी हमारे पास एक से अधिक नेट इंटरफ़ेस होते हैं।

एक विशिष्ट इंटरफ़ेस के मैक पते का पता लगाने की एक सरल विधि है:

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")

2
ओएस एक्स या विंडोज के लिए सुपर उपयोगी नहीं है। : |
रैंडमइन्सानो

1
पाई के लिए बिल्कुल सही!
माइक्ट

8

मेरे उत्तर का उपयोग यहां से करें: https://stackoverflow.com/a/18031868/2362361

यह जानना महत्वपूर्ण होगा कि आप किस मैक को चाहते हैं क्योंकि मैक बहुत से मौजूद हो सकता है (ब्लूटूथ, कई nics, आदि)।

यह तब काम करता है जब आप iface के आईपी को जानते हैं, जिसके लिए आपको MAC की जरूरत होती है, 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'

6

आप इसे 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']
डॉन ली

3

ध्यान दें कि आप सशर्त आयातों का उपयोग करके अजगर में अपने स्वयं के क्रॉस-प्लेटफॉर्म लाइब्रेरी का निर्माण कर सकते हैं। जैसे

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

यह आपको os.system कॉल या प्लेटफ़ॉर्म-विशिष्ट पुस्तकालयों का उपयोग करने की अनुमति देगा।


2
यह वास्तव में एक जवाब नहीं है - सिर्फ एक टिप्पणी
स्टेफ़ानो

1

क्रॉस-प्लेटफ़ॉर्म गेटमैक पैकेज इसके लिए काम करेगा, अगर आपको निर्भरता पर ध्यान नहीं है। यह पायथन 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)

अस्वीकरण: मैं पैकेज का लेखक हूं।

अपडेट (14 जनवरी 2019): पैकेज अब केवल पायथन 2.7+ और 3.4+ का समर्थन करता है। यदि आप पुराने पाइथन (2.5, 2.6, 3.2, 3.3) के साथ काम करना चाहते हैं तो भी आप पैकेज के पुराने संस्करण का उपयोग कर सकते हैं।


1

eth0इंटरफ़ेस मैक पता प्राप्त करने के लिए ,

import psutil

nics = psutil.net_if_addrs()['eth0']

for interface in nics:
   if interface.family == 17:
      print(interface.address)

0

मैं एक एकीकृत तरीके से नहीं जानता, लेकिन कुछ ऐसा है जो आपको उपयोगी लग सकता है:

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

इस मामले में मैं क्या करूंगा कि उन्हें एक फ़ंक्शन में लपेट दिया जाए, और ओएस के आधार पर यह उचित कमांड चलाएगा, आवश्यकतानुसार पार्स करेगा और आप जो चाहें, केवल मैक पते को स्वरूपित करके वापस कर देंगे। इसके सभी समान रूप से, सिवाय इसके कि आपको केवल एक बार करना है, और यह मुख्य कोड से क्लीनर दिखता है।


0

लिनक्स के लिए मुझे एक शेल स्क्रिप्ट शुरू करने की अनुमति देता है जो मैक पते को दिखाएगा और इसे बदलने की अनुमति देगा (मैक सूँघना)।

 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  

मैक को बदलने के लिए हम कर सकते हैं:

ifconfig eth0 down
ifconfig eth0 hw ether 00:80:48:BA:d1:30
ifconfig eth0 up

मैक पते को 00: 80: 48: BA: d1: 30 में बदल देगा (अस्थायी रूप से, रिबूट पर वास्तविक को पुनर्स्थापित करेगा)।


6
क्या इस सवाल के साथ कुछ करना है?
बॉट 47


-8

लिनक्स के लिए आप 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 ...

आपने प्रश्न "अजगर" को टैग किया है। मुझे यह जानकारी प्राप्त करने के लिए मौजूदा पायथन मॉड्यूल का पता नहीं है। आप सीधे ioctl को कॉल करने के लिए ctypes का उपयोग कर सकते हैं ।


8
-1 वह एक अजगर समाधान चाहता है, इसलिए आप जाकर उसे पूरे वेब में पलटा हुआ एक ही regurgitated C solution दें।
5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.