Skip to main content

Like ``ipaddress``, but for hardware identifiers such as MAC addresses.

Project description

A module for handling hardware identifiers like MAC addresses.

This module makes it easy to:

  1. check if a string represents a valid MAC address, or a similar hardware identifier like an EUI-64, OUI, etc,

  2. convert between string and binary forms of MAC addresses and other hardware identifiers,

and so on.

Heavily inspired by the ipaddress module, but not yet quite as featureful.

Versioning

This library’s version numbers follow the SemVer 2.0.0 specification.

Installation

pip install macaddress

Usage

Import:

import macaddress

Classes are provided for common hardware identifier types (MAC/EUI48, EUI64, OUI, and so on), as well as several less common ones. Others might be added later. You can define ones that you need in your code with just a few lines of code.

Parse or Validate String

When only one address type is valid:

All provided classes support the standard and common formats. For example, the EUI48 and MAC classes support the following formats:

>>> macaddress.MAC('01-23-45-67-89-ab')
MAC('01-23-45-67-89-AB')
>>> macaddress.MAC('01:23:45:67:89:ab')
MAC('01-23-45-67-89-AB')
>>> macaddress.MAC('0123.4567.89ab')
MAC('01-23-45-67-89-AB')
>>> macaddress.MAC('0123456789ab')
MAC('01-23-45-67-89-AB')

You can inspect what formats a hardware address class supports by looking at its formats attribute:

>>> macaddress.OUI.formats
('xx-xx-xx', 'xx:xx:xx', 'xxxxxx')

Each x in the format string matches one hexadecimal “digit”, and all other characters are matched literally.

If the string does not match one of the formats, a ValueError is raised:

>>> macaddress.MAC('foo bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/code/m/macaddress.py", line 84, in __init__
    self._address, _ = _parse(address, type(self))
  File "/home/user/code/m/macaddress.py", line 357, in _parse
    raise _value_error(input, 'cannot be parsed as', *classes)
ValueError: 'foo bar' cannot be parsed as MAC

If you need to parse in a format that isn’t supported, you can define a subclass and add the format:

>>> class MACAllowsTrailingDelimiters(macaddress.MAC):
...     formats = macaddress.MAC.formats + (
...         'xx-xx-xx-xx-xx-xx-',
...         'xx:xx:xx:xx:xx:xx:',
...         'xxxx.xxxx.xxxx.',
...         'xxxxxxxxxxxx',
...     )
...
>>> MACAllowsTrailingDelimiters('01-02-03-04-05-06-')
MACAllowsTrailingDelimiters('01-02-03-04-05-06')

When multiple address types are valid:

There is also a parse function for when you have a string which might be one of several classes:

>>> macaddress.parse('01:02:03', macaddress.OUI, macaddress.MAC)
OUI('01-02-03')
>>> macaddress.parse('01:02:03:04:05:06', macaddress.OUI, macaddress.MAC)
MAC('01-02-03-04-05-06')
>>> macaddress.parse('010203040506', macaddress.EUI64, macaddress.EUI48)
EUI48('01-02-03-04-05-06')
>>> macaddress.parse('0102030405060708', macaddress.EUI64, macaddress.EUI48)
EUI64('01-02-03-04-05-06-07-08')

Note that the message of the ValueError tries to be helpful to humans by mentioning what classes you tried to parse it as:

>>> macaddress.parse('x', macaddress.MAC, macaddress.OUI, macaddress.EUI64)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/code/m/macaddress.py", line 335, in parse
    address, cls = _parse(string, *classes)
  File "/home/user/code/m/macaddress.py", line 363, in _parse
    raise _value_error(input, 'cannot be parsed as', *classes)
ValueError: 'x' cannot be parsed as MAC, OUI, or EUI64

Parse from Bytes

All macaddress classes can be constructed from raw bytes:

>>> macaddress.MAC(b'abcdef')
MAC('61-62-63-64-65-66')
>>> macaddress.OUI(b'abc')
OUI('61-62-63')

If the byte string is the wrong size, a ValueError is raised:

>>> macaddress.MAC(b'\x01\x02\x03')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/code/m/macaddress.py", line 86, in __init__
    raise _value_error(address, 'has wrong length for', type(self))
ValueError: b'\x01\x02\x03' has wrong length for MAC

Parse from Integers

All macaddress classes can be constructed from raw integers:

>>> macaddress.MAC(0x010203ffeedd)
MAC('01-02-03-FF-EE-DD')
>>> macaddress.OUI(0x010203)
OUI('01-02-03')

Note that the least-significant bit of the integer value maps to the last bit in the address type, so the same integer has a different meaning depending on the class you use it with:

>>> macaddress.MAC(1)
MAC('00-00-00-00-00-01')
>>> macaddress.OUI(1)
OUI('00-00-01')

If the integer is too large for the hardware identifier class that you’re trying to construct, a ValueError is raised:

>>> macaddress.OUI(1_000_000_000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/code/m/macaddress.py", line 78, in __init__
    raise _value_error(address, 'is too big for', type(self))
ValueError: 1000000000 is too big for OUI

Get as String

>>> mac = macaddress.MAC('01-02-03-04-05-06')
>>> str(mac)
01-02-03-04-05-06

The first format listed in formats is used when stringifying the object. If you want to use a different format, you can override the formats attribute on the instance, or on a subclass:

>>> mac.formats = ('xx:xx:xx:xx:xx:xx',)
>>> str(mac)
01-02-03-04-05-06

>>> class MACWithColonsByDefault(macaddress.MAC):
...     formats = ('xx:xx:xx:xx:xx:xx',) + macaddress.MAC.formats
...
>>> MACWithColonsByDefault('ab:cd:ef:01:02:03')
MACWithColonsByDefault('AB:CD:EF:01:02:03')
>>> str(MACWithColonsByDefault('ab-cd-ef-01-02-03'))
AB:CD:EF:01:02:03

Note that appending the original formats tuple to the new custom formats ensures that you can still parse all the valid formats.

Get as Bytes

>>> mac = macaddress.MAC('61-62-63-04-05-06')
>>> bytes(mac)
b'abc\x04\x05\x06'

Get as Integer

>>> mac = macaddress.MAC('01-02-03-04-05-06')
>>> int(mac)
1108152157446
>>> int(mac) == 0x010203040506
True

Get the OUI

Most classes supplied by this module have the oui attribute, which returns their first three bytes as an OUI object:

>>> macaddress.MAC('01:02:03:04:05:06').oui
OUI('01-02-03')

Compare

Equality

All macaddress classes support equality comparisons:

>>> macaddress.OUI('01-02-03') == macaddress.OUI('01:02:03')
True
>>> macaddress.OUI('01-02-03') == macaddress.OUI('ff-ee-dd')
False
>>> macaddress.OUI('01-02-03') != macaddress.CDI32('01-02-03-04')
True
>>> macaddress.OUI('01-02-03') != macaddress.CDI32('01-02-03-04').oui
False

Ordering

All macaddress classes support total ordering. The comparisons are designed to intuitively sort identifiers that start with the same bits next to each other:

>>> some_values = [
...     MAC('ff-ee-dd-01-02-03'),
...     MAC('ff-ee-00-99-88-77'),
...     MAC('ff-ee-dd-01-02-04'),
...     OUI('ff-ee-dd'),
... ]
>>> for x in sorted(some_values):
...     print(x)
FF-EE-00-01-02-03
FF-EE-DD
FF-EE-DD-01-02-03
FF-EE-DD-01-02-04

Define New Types

This library is designed to make it very easy to use other hardware address types that this library does not currently define for you.

For example, if you want to handle IP-over-InfiniBand link-layer addresses, all you need to define is:

class InfiniBand(macaddress.HWAddress):
    size = 20 * 8  # size in bits; 20 octets

    formats = (
        'xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx',
        'xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx',
        'xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx',
        'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        # or whatever formats you want to support
    )

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

macaddress-1.0.1.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

macaddress-1.0.1-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file macaddress-1.0.1.tar.gz.

File metadata

  • Download URL: macaddress-1.0.1.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.5.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for macaddress-1.0.1.tar.gz
Algorithm Hash digest
SHA256 e020d8d5cd3eeb7fe581591db0290f3c77680dd27f8c593e7dbcb1f2ff3668af
MD5 da1e5af340ebd9d962ade42899ae1635
BLAKE2b-256 db1739c255413f55a9e0bbbe2672b10c6c4d0b9f6b6c34c18ef9a21c12e32204

See more details on using hashes here.

File details

Details for the file macaddress-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: macaddress-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.5.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for macaddress-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 45b09417a8290e58b0eaf7e07d085ac7feb9cc0c1b5f16b8faac9c11ccd1fe95
MD5 0df7f8f6d7c9574c5db731d5929d16d4
BLAKE2b-256 4593a58ff033b1915ab1935ccec569e591398447d727139dd031fba14516dab5

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page