Elegant Format for a MAC Address in Python 3.2

后端 未结 8 2157
无人及你
无人及你 2020-12-19 00:46

I am looking for a more elegant solution to formatting a MAC address with colons. I am using Python 3.2. A fancy list comprehension perhaps?

s=\"\"
h=\"0023         


        
相关标签:
8条回答
  • 2020-12-19 01:05

    Well, I might start with something pretty specific, since you know that it is an MAC address you know the exact size and format.

    print "%s:%s:%s:%s:%s:%s" % (h[0:2], h[2:4], h[4:6], h[6:8], h[8:10], h[10:12])
    

    But we can make this better if we create a class and then tell it how to format it's string.

    class Mac():
        def __init__(self, mac):
            self.mac = mac
        def __str__(self):
            return "%s:%s:%s:%s:%s:%s" % (
                self.mac[0:2],
                self.mac[2:4],
                self.mac[4:6],
                self.mac[6:8],
                self.mac[8:10],
                self.mac[10:12])
    
    m = Mac("123456789012")
    print m
    
    0 讨论(0)
  • 2020-12-19 01:12
    from netaddr import EUI, mac_unix_expanded
    print(EUI('00:01:02:03:04:05', dialect=mac_unix_expanded))
    print(EUI('1-2-3-4-5-6', dialect=mac_unix_expanded))
    
    0 讨论(0)
  • 2020-12-19 01:12

    Not sure how pretty this is, but it will do what you ask:

    ':'.join([h[i:i+2] for i,j in enumerate(h) if not (i%2)])
    

    gives:

    '00:23:3a:99:0c:21'
    
    0 讨论(0)
  • 2020-12-19 01:22

    Your code is easily converted to a comprehension form:

    ':'.join(h[i:i+2] for i in range(0,12,2))
    
    0 讨论(0)
  • 2020-12-19 01:22

    This is not the shortest solution, but it accepts all common types of mac formats as inputs. It also does some validation checks.

    import re
    
    def format_mac(mac: str) -> str:
        mac = re.sub('[.:-]', '', mac).lower()  # remove delimiters and convert to lower case
        mac = ''.join(mac.split())  # remove whitespaces
        assert len(mac) == 12  # length should be now exactly 12 (eg. 008041aefd7e)
        assert mac.isalnum()  # should only contain letters and numbers
        # convert mac in canonical form (eg. 00:80:41:ae:fd:7e)
        mac = ":".join(["%s" % (mac[i:i+2]) for i in range(0, 12, 2)])
        return mac
    

    Here is a list of mac address strings and whether they will be considered as valid or invalid:

    '008041aefd7e',  # valid
    '00:80:41:ae:fd:7e',  # valid
    '00:80:41:AE:FD:7E',  # valid
    '00:80:41:aE:Fd:7E',  # valid
    '00-80-41-ae-fd-7e',  # valid
    '0080.41ae.fd7e',  # valid
    '00 : 80 : 41 : ae : fd : 7e',  # valid
    '  00:80:41:ae:fd:7e  ',  # valid
    '00:80:41:ae:fd:7e\n\t',  # valid
    
    'aa:00:80:41:ae:fd:7e',  # invalid
    '0:80:41:ae:fd:7e',  # invalid
    'ae:fd:7e',  # invalid
    '$$:80:41:ae:fd:7e',  # invalid
    

    All valid ones will be returned in the canonical form as:

    '00:80:41:ae:fd:7e'
    
    0 讨论(0)
  • 2020-12-19 01:23

    The easiest solution here is just to use str.join()

    >>> ":".join(str_grouper(2, "00233a990c21"))
    '00:23:3a:99:0c:21'
    

    Here using a modified version of the grouper() recipe from the itertools docs:

    def str_grouper(n, iterable):
         args = [iter(iterable)] * n
         for part in zip(*args): #itertools.izip in 2.x for efficiency.
             yield "".join(part)
    
    0 讨论(0)
提交回复
热议问题