简体   繁体   中英

How do I validate the format of a MAC address?

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.

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.

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

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
private static final String MAC_PATTERN = "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$";

private boolean validateMAC(final String mac){          
          Pattern pattern = Pattern.compile(MAC_PATTERN);
          Matcher matcher = pattern.matcher(mac);
          return matcher.matches();             
    }

Dash-separated MAC addresses can also contain a '01-' prefix, which specifies it is an Ethernet MAC address (not token ring, for example ... who uses token ring?).

Here's something that is somewhat complete and easy to read in a logical step-through way:

def IsMac(S):
  digits = S.split(':')
  if len(digits) == 1:
    digits = S.split('-')
    if len(digits) == 7:
      if digits[0] != '01':
        return False
      digits.pop(0)
  if len(digits) != 6:
    return False
  for digit in digits:
    if len(digit) != 2:
      return False
    try:
      int(digit, 16)
    except ValueError:
      return False
  return True


for test in ('01-07-09-07-b4-ff-a7',  # True
                '07:09:07:b4:ff:a7',  # True
                '07-09-07-b4-GG-a7',  # False
                 '7-9-7-b4-F-a7',     # False
                 '7-9-7-b4-0xF-a7'):  # False
  print test, IsMac(test)
import re

def MacValidator(inputMacList):
    def MacParser(mac):
        octets = re.split('[\:\-]', mac)
        if len(octets) != 6:
            return False
        for i in octets:
            try:
                if int(i, 16) > 255:
                    return False
            except:
                return False
        return mac

    return [i.upper() for i in inputMacList if MacParser(i) != False]

macList = ["00-15-F2-20-4D-6B", "Kozel", "00:13:aa:00:00:01",
           "00:13:AA:00:tr:01", "00-01-01-20-55-55", "00-01-01-20abc-55"]

validMacList = MacValidator(macList)

I cheated and used combination of multiple answers submitted by other people. I think this is pretty clear and straight forward one liner. mac_validation should return True or False .

import re
mac_validation = bool(re.match('^' + '[\:\-]'.join(['([0-9a-f]{2})']*6) + '$', mac_input.lower()))

This Regex validates the following MAC format

"Ae:Bd:00:00:00:00"
"00-00-00-00-00-00"
"aaaa.bbbb.cccc"
private static final String MAC_PATTERN = "(([0-9A-Fa-f]{2}[-:.]){5}[0-9A-Fa-f]{2})|(([0-9A-Fa-f]{4}\\.){2}[0-9A-Fa-f]{4})";

public class MacRegExp {

    private static final String MAC_PATTERN = "(([0-9A-Fa-f]{2}[-:.]){5}[0-9A-Fa-f]{2})|(([0-9A-Fa-f]{4}\\.){2}[0-9A-Fa-f]{4})";

    static boolean validateMAC(final String mac){          
        Pattern pattern = Pattern.compile(MAC_PATTERN);
        Matcher matcher = pattern.matcher(mac);
        return matcher.matches();             
    }

}

Hope this helps

This works like a charm.

def isMAC48Address(inputString):
    if inputString.count(":")!=5:
        return False
    for i in inputString.split(":"):
        for j in i:
            if j>"F" or (j<"A" and not j.isdigit()) or len(i)!=2:
                return False
    return True 
#Just works Perfect
#validate the MAC addr

#!/usr/bin/python
import re

mac = "01-3e-4f-ee-23-af"

result = re.match(r"([0-9a-fA-F]{2}[-:]){5}[0-9a-fA-F]{2}$",mac)

if result:
    print ("Correct MAC")
else:
    print ("Incorrect MAC")
pattern = "^(([0-9]{2}|[a-f]{2}|[0-9][a-f]|[a-f][0-9])\:){5}([0-9]{2}|[a-f]{2}|[0-9][a-f]|[a-f]|[0-9])$"

valid_mac_check =re.search(pattern,"00:29:15:80:4E:4A",re.IGNORECASE)
print(valid_mac_check.group())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM