Как проверить формат MAC-адреса?

Каков наилучший способ проверки того, что MAC-адрес, введенный пользователем?

Формат HH:HH:HH:HH:HH:HH, где каждый H является шестнадцатеричным символом.

Например, 00:29:15:80:4E:4A допустим, а 00:29:804E4A является недопустимым.

Ответ 1

Если вы имеете в виду только синтаксис, то это регулярное выражение должно работать для вас

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

он принимает 12 шестнадцатеричных цифр с : или - или ничем в качестве разделителей между парами (но разделитель должен быть равномерным... либо все разделители являются : или являются всеми - или разделителя нет).

Это объяснение:

  • [0-9a-f] означает шестнадцатеричное число
  • {2} означает, что мы хотим два из них
  • [-:]? означает или тире или двоеточие, но необязательно. Обратите внимание, что черта в качестве первого символа не означает диапазон, а означает только себя. Это подвыражение заключено в круглые скобки, поэтому его можно использовать позже в качестве обратной ссылки.
  • [0-9a-f]{2} - другая пара шестнадцатеричных цифр
  • \\1 это означает, что мы хотим сопоставить то же выражение, что и ранее, в качестве разделителя. Это то, что гарантирует единообразие. Обратите внимание, что синтаксис регулярного выражения равен \1 но я использую обычную строку, поэтому обратную косую черту необходимо экранировать, удваивая ее.
  • [0-9a-f]{2} другая пара шестнадцатеричных цифр
  • {4} предыдущий заключенный в скобки блок должен быть повторен ровно 4 раза, давая в общей сложности 6 пар цифр: <pair> [<sep>] <pair> (<same-sep> <pair> ) * 4
  • $ Строка должна заканчиваться сразу после них

Обратите внимание, что в Python re.match проверяет только начало в начале строки и, следовательно, re.match ^ в начале не требуется.

Ответ 2

Я ненавижу программы, которые заставляют пользователя думать как компьютер.

Сделайте его более дружественным, приняв любой допустимый формат.

Разделите разделитель, что бы это ни было, затем получите оставшееся шестнадцатеричное значение. Таким образом, если пользователь вводит тире или пробелы, он также работает.

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

Ответ 3

Если вы хотите убедиться, что в Python есть либо "-", либо ":", но не оба, вы можете использовать следующее в 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

Ответ 4

Это работает как шарм.

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 

Ответ 5

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();             
    }

Ответ 6

MAC-адреса, разделенные запятыми, также могут содержать префикс '01 - ', который указывает, что это MAC-адрес Ethernet (например, не Token Ring, кто использует кольцо Token Ring?).

Здесь что-то, что несколько полнее и легко читается логичным сквозным способом:

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)

Ответ 7

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)

Ответ 8

Я обманул и использовал комбинацию нескольких ответов, представленных другими людьми. Я думаю, это довольно ясно и прямо вперед один лайнер. mac_validation должен возвращать True или False.

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

Ответ 9

Это регулярное выражение проверяет следующий формат MAC

"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();             
    }

}

Надеюсь, что это поможет