Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I validate the format of a MAC address?

Tags:

python

What's the best way to validate that an MAC address entered by the user?

The format is HH:HH:HH:HH:HH:HH, where each H is a hexadecimal character.

For instance, 00:29:15:80:4E:4A is valid while 00:29:804E4A is invalid.

like image 824
Manu Mora Avatar asked Oct 02 '11 22:10

Manu Mora


People also ask

What does a valid MAC address look like?

A MAC address is a 48-bit hexadecimal address. It's usually six sets of two digits or characters, separated by colons. An example MAC address would be 00:00:5e:00:53:af. Many network card and other hardware manufacturers use a unique sequence at the beginning of their products' MAC addresses.

What format is used to represent a MAC address?

Format of MAC Address – MAC Address is a 12-digit hexadecimal number (6-Byte binary number), which is mostly represented by Colon-Hexadecimal notation. The First 6-digits (say 00:40:96) of MAC Address identifies the manufacturer, called OUI (Organizational Unique Identifier).

Which of the following is not a valid MAC address?

The correct answer is 00-11-20-M1-BC-B0, because the MAC address consists of 6 groups of Hexadecimal characters and the letter M in the 3rd group is the only character that is not a Hexadecimal character.

Are all MAC addresses 12 digits?

Both methods use MAC addresses to identify a device on the network. A MAC address is responsible for local identification and an IP address for global identification. A MAC address consists of 12 hexadecimal digits, usually grouped into six pairs separated by hyphens.


3 Answers

If you mean just the syntax then this regexp should work for you

import re
...
if re.match("[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", x.lower()):
    ...

it accepts 12 hex digits with either : or - or nothing as separators between pairs (but the separator must be uniform... either all separators are : or are all - or there is no separator).

This is the explanation:

  • [0-9a-f] means an hexadecimal digit
  • {2} means that we want two of them
  • [-:]? means either a dash or a colon but optional. Note that the dash as first char doesn't mean a range but only means itself. This subexpression is enclosed in parenthesis so it can be reused later as a back reference.
  • [0-9a-f]{2} is another pair of hexadecimal digits
  • \\1 this means that we want to match the same expression that we matched before as separator. This is what guarantees uniformity. Note that the regexp syntax is \1 but I'm using a regular string so backslash must be escaped by doubling it.
  • [0-9a-f]{2} another pair of hex digits
  • {4} the previous parenthesized block must be repeated exactly 4 times, giving a total of 6 pairs of digits: <pair> [<sep>] <pair> ( <same-sep> <pair> ) * 4
  • $ The string must end right after them

Note that in Python re.match only checks starting at the start of the string and therefore a ^ at the beginning is not needed.

like image 166
6502 Avatar answered Oct 16 '22 10:10

6502


I hate programs that force the user to think a like a computer.

Make it more friendly by accepting any valid format.

Strip the separator, whatever it is, then get the hex value that's left. That way if a user enters dashes or spaces it also works.

import string
allchars = "".join(chr(a) for a in range(256))
delchars = set(allchars) - set(string.hexdigits)

def checkMAC(s):
  mac = s.translate("".join(allchars),"".join(delchars))
  if len(mac) != 12:
      raise ValueError, "Ethernet MACs are always 12 hex characters, you entered %s" % mac 
  return mac.upper()


checkMAC("AA:BB:CC:DD:EE:FF")
checkMAC("00-11-22-33-44-66")
checkMAC("1 2 3 4 5 6 7 8 9 a b c")
checkMAC("This is not a mac")
like image 3
Jason M Avatar answered Oct 16 '22 10:10

Jason M


If you want to ensure that there is either '-' or ':' throughout but not both, you can use following in Python:

import re

def is_valid_macaddr802(value):
    allowed = re.compile(r"""
                         (
                             ^([0-9A-F]{2}[-]){5}([0-9A-F]{2})$
                            |^([0-9A-F]{2}[:]){5}([0-9A-F]{2})$
                         )
                         """,
                         re.VERBOSE|re.IGNORECASE)

    if allowed.match(value) is None:
        return False
    else:
        return True
like image 1
Abhiraj Butala Avatar answered Oct 16 '22 09:10

Abhiraj Butala