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