macaddress


Namemacaddress JSON
Version 2.0.2 PyPI version JSON
download
home_pagehttps://github.com/mentalisttraceur/python-macaddress
SummaryLike ``ipaddress``, but for hardware identifiers such as MAC addresses.
upload_time2022-11-04 21:31:19
maintainer
docs_urlNone
authorAlexander Kozhevnikov
requires_python
license0BSD
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            macaddress
==========

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 <https://semver.org/spec/v2.0.0.html>`_.


Installation
------------

::

    pip install macaddress


Usage
-----

Import:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

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


Get as String
~~~~~~~~~~~~~

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

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


Get as Bytes
~~~~~~~~~~~~

.. code:: python

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


Get as Integer
~~~~~~~~~~~~~~

.. code:: python

    >>> 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:

.. code:: python

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


Compare
~~~~~~~

Equality
````````

All ``macaddress`` classes support equality comparisons:

.. code:: python

    >>> 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:

.. code:: python

    >>> 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:

.. code:: python

    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.



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/mentalisttraceur/python-macaddress",
    "name": "macaddress",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "",
    "author": "Alexander Kozhevnikov",
    "author_email": "mentalisttraceur@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/dc/0f/e9b1028826cef8aa8d5f187b9fe2fd8f5b8c8ca393a11cffbcbe58f8a247/macaddress-2.0.2.tar.gz",
    "platform": null,
    "description": "macaddress\n==========\n\nA module for handling hardware identifiers like MAC addresses.\n\nThis module makes it easy to:\n\n1. check if a string represents a valid MAC address, or a similar\n   hardware identifier like an EUI-64, OUI, etc,\n\n2. convert between string and binary forms of MAC addresses and\n   other hardware identifiers,\n\nand so on.\n\nHeavily inspired by the ``ipaddress`` module, but not yet quite\nas featureful.\n\n\nVersioning\n----------\n\nThis library's version numbers follow the `SemVer 2.0.0\nspecification <https://semver.org/spec/v2.0.0.html>`_.\n\n\nInstallation\n------------\n\n::\n\n    pip install macaddress\n\n\nUsage\n-----\n\nImport:\n\n.. code:: python\n\n    >>> import macaddress\n\nClasses are provided for the common hardware identifier\ntypes: ``EUI48`` (also available as ``MAC``), ``EUI64``,\n``OUI``, and so on. If those aren't enough, you can\neasily define others with just a few lines of code.\n\n\nParse or Validate String\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen only one address type is valid:\n````````````````````````````````````\n\nAll provided classes support the standard and common formats.\nFor example, the ``EUI48`` class supports the following\nformats:\n\n.. code:: python\n\n    >>> macaddress.EUI48('01-23-45-67-89-ab')\n    EUI48('01-23-45-67-89-AB')\n    >>> macaddress.EUI48('01:23:45:67:89:ab')\n    EUI48('01-23-45-67-89-AB')\n    >>> macaddress.EUI48('0123.4567.89ab')\n    EUI48('01-23-45-67-89-AB')\n    >>> macaddress.EUI48('0123456789ab')\n    EUI48('01-23-45-67-89-AB')\n\nYou can inspect what formats a hardware address class supports\nby looking at its ``formats`` attribute:\n\n.. code:: python\n\n    >>> macaddress.OUI.formats\n    ('xx-xx-xx', 'xx:xx:xx', 'xxxxxx')\n\nEach ``x`` in the format string matches one hexadecimal\n\"digit\", and all other characters are matched literally.\n\nIf the string does not match one of the formats, a\n``ValueError`` is raised:\n\n.. code:: python\n\n    >>> try:\n    ...     macaddress.MAC('foo bar')\n    ... except ValueError as error:\n    ...     print(error)\n    ...\n    'foo bar' cannot be parsed as EUI48\n\nIf you need to parse in a format that isn't supported,\nyou can define a subclass and add the formats:\n\n.. code:: python\n\n    >>> class MAC(macaddress.MAC):\n    ...     formats = macaddress.MAC.formats + (\n    ...         'xx-xx-xx-xx-xx-xx-',\n    ...         'xx:xx:xx:xx:xx:xx:',\n    ...         'xxxx.xxxx.xxxx.',\n    ...     )\n    ...\n    >>> MAC('01-02-03-04-05-06-')\n    MAC('01-02-03-04-05-06')\n\n    >>> class MAC(macaddress.MAC):\n    ...     formats = macaddress.MAC.formats + (\n    ...         'xxx-xxx-xxx-xxx',\n    ...         'xxx xxx xxx xxx',\n    ...         'xxx:xxx:xxx:xxx',\n    ...         'xxx.xxx.xxx.xxx',\n    ...     )\n    ...\n    >>> MAC('012 345 678 9AB')\n    MAC('01-23-45-67-89-AB')\n\nWhen multiple address types are valid:\n``````````````````````````````````````\n\nThere is also a ``parse`` function for when you have a string\nwhich might be one of several classes:\n\n.. code:: python\n\n    >>> from macaddress import EUI48, EUI64, OUI\n\n    >>> macaddress.parse('01:02:03', OUI, EUI48)\n    OUI('01-02-03')\n    >>> macaddress.parse('01:02:03:04:05:06', OUI, EUI48, EUI64)\n    EUI48('01-02-03-04-05-06')\n    >>> macaddress.parse('010203040506', EUI64, EUI48)\n    EUI48('01-02-03-04-05-06')\n    >>> macaddress.parse('0102030405060708', EUI64, EUI48, OUI)\n    EUI64('01-02-03-04-05-06-07-08')\n\nIf the input string cannot be parsed as any of\nthe given classes, a ``ValueError`` is raised:\n\n.. code:: python\n\n    >>> try:\n    ...     macaddress.parse('01:23', EUI48, OUI)\n    ... except ValueError as error:\n    ...     print(error)\n    ...\n    '01:23' cannot be parsed as EUI48 or OUI\n    >>> try:\n    ...     macaddress.parse('01:23', EUI48, OUI, EUI64)\n    ... except ValueError as error:\n    ...     print(error)\n    ...\n    '01:23' cannot be parsed as EUI48, OUI, or EUI64\n\nNote that the message of the ``ValueError`` tries to be helpful\nfor developers, but it is not localized, nor is its exact text\npart of the official public interface covered by SemVer.\n\n\nParse from Bytes\n~~~~~~~~~~~~~~~~\n\nAll ``macaddress`` classes can be constructed from raw bytes:\n\n.. code:: python\n\n    >>> macaddress.MAC(b'abcdef')\n    EUI48('61-62-63-64-65-66')\n    >>> macaddress.OUI(b'abc')\n    OUI('61-62-63')\n\nIf the byte string is the wrong size, a ``ValueError`` is raised:\n\n.. code:: python\n\n    >>> try:\n    ...     macaddress.MAC(b'\\x01\\x02\\x03')\n    ... except ValueError as error:\n    ...     print(error)\n    ...\n    b'\\x01\\x02\\x03' has wrong length for EUI48\n\n\nParse from Integers\n~~~~~~~~~~~~~~~~~~~\n\nAll ``macaddress`` classes can be constructed from raw integers:\n\n.. code:: python\n\n    >>> macaddress.MAC(0x010203ffeedd)\n    EUI48('01-02-03-FF-EE-DD')\n    >>> macaddress.OUI(0x010203)\n    OUI('01-02-03')\n\nNote that the least-significant bit of the integer value maps\nto the last bit in the address type, so the same integer has\na different meaning depending on the class you use it with:\n\n.. code:: python\n\n    >>> macaddress.MAC(1)\n    EUI48('00-00-00-00-00-01')\n    >>> macaddress.OUI(1)\n    OUI('00-00-01')\n\nIf the integer is too large for the hardware identifier class\nthat you're trying to construct, a ``ValueError`` is raised:\n\n.. code:: python\n\n    >>> try:\n    ...     macaddress.OUI(1_000_000_000)\n    ... except ValueError as error:\n    ...     print(error)\n    ...\n    1000000000 is too big for OUI\n\n\nGet as String\n~~~~~~~~~~~~~\n\n.. code:: python\n\n    >>> mac = macaddress.MAC('01-02-03-0A-0B-0C')\n    >>> str(mac)\n    '01-02-03-0A-0B-0C'\n\nFor simple cases of changing the output format, you\ncan just compose string operations:\n\n.. code:: python\n\n    >>> str(mac).replace('-', ':')\n    '01:02:03:0A:0B:0C'\n    >>> str(mac).replace('-', '')\n    '0102030A0B0C'\n    >>> str(mac).lower()\n    '01-02-03-0a-0b-0c'\n\nFor more complicated cases, you can define a subclass\nwith the desired output format as the first format:\n\n.. code:: python\n\n    >>> class MAC(macaddress.MAC):\n    ...     formats = (\n    ...         'xxx xxx xxx xxx',\n    ...     ) + macaddress.MAC.formats\n    ...\n    >>> MAC(mac)\n    MAC('010 203 0A0 B0C')\n\n\nGet as Bytes\n~~~~~~~~~~~~\n\n.. code:: python\n\n    >>> mac = macaddress.MAC('61-62-63-04-05-06')\n    >>> bytes(mac)\n    b'abc\\x04\\x05\\x06'\n\n\nGet as Integer\n~~~~~~~~~~~~~~\n\n.. code:: python\n\n    >>> mac = macaddress.MAC('01-02-03-04-05-06')\n    >>> int(mac)\n    1108152157446\n    >>> int(mac) == 0x010203040506\n    True\n\n\nGet the OUI\n~~~~~~~~~~~\n\nMost classes supplied by this module have the ``oui``\nattribute, which returns their first three bytes as\nan OUI object:\n\n.. code:: python\n\n    >>> macaddress.MAC('01:02:03:04:05:06').oui\n    OUI('01-02-03')\n\n\nCompare\n~~~~~~~\n\nEquality\n````````\n\nAll ``macaddress`` classes support equality comparisons:\n\n.. code:: python\n\n    >>> macaddress.OUI('01-02-03') == macaddress.OUI('01:02:03')\n    True\n    >>> macaddress.OUI('01-02-03') == macaddress.OUI('ff-ee-dd')\n    False\n    >>> macaddress.OUI('01-02-03') != macaddress.CDI32('01-02-03-04')\n    True\n    >>> macaddress.OUI('01-02-03') != macaddress.CDI32('01-02-03-04').oui\n    False\n\nOrdering\n````````\n\nAll ``macaddress`` classes support total\nordering. The comparisons are designed to\nintuitively sort identifiers that start\nwith the same bits next to each other:\n\n.. code:: python\n\n    >>> some_values = [\n    ...     macaddress.MAC('ff-ee-dd-01-02-03'),\n    ...     macaddress.MAC('ff-ee-00-99-88-77'),\n    ...     macaddress.MAC('ff-ee-dd-01-02-04'),\n    ...     macaddress.OUI('ff-ee-dd'),\n    ... ]\n    >>> for x in sorted(some_values):\n    ...     print(x)\n    FF-EE-00-99-88-77\n    FF-EE-DD\n    FF-EE-DD-01-02-03\n    FF-EE-DD-01-02-04\n\n\nDefine New Types\n~~~~~~~~~~~~~~~~\n\nIf this library does not provide a hardware address\ntype that you need, you can easily define your own.\n\nFor example, this is all it takes to define\nIP-over-InfiniBand link-layer addresses:\n\n.. code:: python\n\n    class InfiniBand(macaddress.HWAddress):\n        size = 20 * 8  # size in bits; 20 octets\n\n        formats = (\n            'xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx',\n            'xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx',\n            'xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx',\n            'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n            # or whatever formats you want to support\n        )\n        # All formats are tried when parsing from string,\n        # and the first format is used when stringifying.\n\n\n",
    "bugtrack_url": null,
    "license": "0BSD",
    "summary": "Like ``ipaddress``, but for hardware identifiers such as MAC addresses.",
    "version": "2.0.2",
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "d9556c1a02ed54a8045b52923d4b6c4c",
                "sha256": "6f4a0430f9b5af6d98a582b8d527ba2cd3f0825fce5503a9ce5c73acb772c30f"
            },
            "downloads": -1,
            "filename": "macaddress-2.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d9556c1a02ed54a8045b52923d4b6c4c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 8027,
            "upload_time": "2022-11-04T21:31:17",
            "upload_time_iso_8601": "2022-11-04T21:31:17.095333Z",
            "url": "https://files.pythonhosted.org/packages/6e/40/cfad5b515667b0465a3169757b5c9f17639dc1da145c65248e5b9fe481d8/macaddress-2.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "5b19c092a3e093f83139de62407492c9",
                "sha256": "1400ccdc28d747102d57ae61e5b78d8985872930810ceb8860cd49abd1e1fa37"
            },
            "downloads": -1,
            "filename": "macaddress-2.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "5b19c092a3e093f83139de62407492c9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 7927,
            "upload_time": "2022-11-04T21:31:19",
            "upload_time_iso_8601": "2022-11-04T21:31:19.106067Z",
            "url": "https://files.pythonhosted.org/packages/dc/0f/e9b1028826cef8aa8d5f187b9fe2fd8f5b8c8ca393a11cffbcbe58f8a247/macaddress-2.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-11-04 21:31:19",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "mentalisttraceur",
    "github_project": "python-macaddress",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "macaddress"
}
        
Elapsed time: 0.01519s