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 the common hardware identifier types: EUI48 (also available as MAC), EUI64, OUI, and so on. If those aren’t enough, you can easily define others 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 class supports the following formats:

>>> macaddress.EUI48('01-23-45-67-89-ab')
EUI48('01-23-45-67-89-AB')
>>> macaddress.EUI48('01:23:45:67:89:ab')
EUI48('01-23-45-67-89-AB')
>>> macaddress.EUI48('0123.4567.89ab')
EUI48('01-23-45-67-89-AB')
>>> macaddress.EUI48('0123456789ab')
EUI48('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:

>>> try:
...     macaddress.MAC('foo bar')
... except ValueError as error:
...     print(error)
...
'foo bar' cannot be parsed as EUI48

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

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

>>> class MAC(macaddress.MAC):
...     formats = macaddress.MAC.formats + (
...         'xxx-xxx-xxx-xxx',
...         'xxx xxx xxx xxx',
...         'xxx:xxx:xxx:xxx',
...         'xxx.xxx.xxx.xxx',
...     )
...
>>> MAC('012 345 678 9AB')
MAC('01-23-45-67-89-AB')

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:

>>> from macaddress import EUI48, EUI64, OUI

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

If the input string cannot be parsed as any of the given classes, a ValueError is raised:

>>> try:
...     macaddress.parse('01:23', EUI48, OUI)
... except ValueError as error:
...     print(error)
...
'01:23' cannot be parsed as EUI48 or OUI
>>> try:
...     macaddress.parse('01:23', EUI48, OUI, EUI64)
... except ValueError as error:
...     print(error)
...
'01:23' cannot be parsed as EUI48, OUI, or EUI64

Note that the message of the ValueError tries to be helpful for developers, but it is not localized, nor is its exact text part of the official public interface covered by SemVer.

Parse from Bytes

All macaddress classes can be constructed from raw bytes:

>>> macaddress.MAC(b'abcdef')
EUI48('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:

>>> try:
...     macaddress.MAC(b'\x01\x02\x03')
... except ValueError as error:
...     print(error)
...
b'\x01\x02\x03' has wrong length for EUI48

Parse from Integers

All macaddress classes can be constructed from raw integers:

>>> macaddress.MAC(0x010203ffeedd)
EUI48('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)
EUI48('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:

>>> try:
...     macaddress.OUI(1_000_000_000)
... except ValueError as error:
...     print(error)
...
1000000000 is too big for OUI

Get as String

>>> mac = macaddress.MAC('01-02-03-0A-0B-0C')
>>> str(mac)
'01-02-03-0A-0B-0C'

For simple cases of changing the output format, you can just compose string operations:

>>> str(mac).replace('-', ':')
'01:02:03:0A:0B:0C'
>>> str(mac).replace('-', '')
'0102030A0B0C'
>>> str(mac).lower()
'01-02-03-0a-0b-0c'

For more complicated cases, you can define a subclass with the desired output format as the first format:

>>> class MAC(macaddress.MAC):
...     formats = (
...         'xxx xxx xxx xxx',
...     ) + macaddress.MAC.formats
...
>>> MAC(mac)
MAC('010 203 0A0 B0C')

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

Define New Types

If this library does not provide a hardware address type that you need, you can easily define your own.

For example, this is all it takes to define IP-over-InfiniBand link-layer addresses:

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
    )
    # All formats are tried when parsing from string,
    # and the first format is used when stringifying.

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-2.0.2.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

macaddress-2.0.2-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: macaddress-2.0.2.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.8

File hashes

Hashes for macaddress-2.0.2.tar.gz
Algorithm Hash digest
SHA256 1400ccdc28d747102d57ae61e5b78d8985872930810ceb8860cd49abd1e1fa37
MD5 5b19c092a3e093f83139de62407492c9
BLAKE2b-256 dc0fe9b1028826cef8aa8d5f187b9fe2fd8f5b8c8ca393a11cffbcbe58f8a247

See more details on using hashes here.

File details

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

File metadata

  • Download URL: macaddress-2.0.2-py3-none-any.whl
  • Upload date:
  • Size: 8.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.8

File hashes

Hashes for macaddress-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6f4a0430f9b5af6d98a582b8d527ba2cd3f0825fce5503a9ce5c73acb772c30f
MD5 d9556c1a02ed54a8045b52923d4b6c4c
BLAKE2b-256 6e40cfad5b515667b0465a3169757b5c9f17639dc1da145c65248e5b9fe481d8

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