Package: macaddress
A module for handling hardware identifiers like MAC addresses.This module makes it easy to:check if a string represents a valid MAC address, or a similar
hardware identifier like an EUI-64, OUI, etc,convert between string and binary forms of MAC addresses and
other hardware identifiers,and so on.Heavily inspired by theipaddressmodule, but not yet quite
as featureful.VersioningThis library’s version numbers follow theSemVer 2.0.0
specification.Installationpip install macaddressUsageImport:>>>importmacaddressClasses are provided for the common hardware identifier
types:EUI48(also available asMAC),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 StringWhen only one address type is valid:All provided classes support the standard and common formats.
For example, theEUI48class 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 itsformatsattribute:>>>macaddress.OUI.formats('xx-xx-xx','xx:xx:xx','xxxxxx')Eachxin the format string matches one hexadecimal
“digit”, and all other characters are matched literally.If the string does not match one of the formats, aValueErroris raised:>>>try:...macaddress.MAC('foo bar')...exceptValueErroraserror:...print(error)...'foo bar'cannotbeparsedasEUI48If you need to parse in a format that isn’t supported,
you can define a subclass and add the formats:>>>classMAC(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')>>>classMAC(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 aparsefunction for when you have a string
which might be one of several classes:>>>frommacaddressimportEUI48,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, aValueErroris raised:>>>try:...macaddress.parse('01:23',EUI48,OUI)...exceptValueErroraserror:...print(error)...'01:23'cannotbeparsedasEUI48orOUI>>>try:...macaddress.parse('01:23',EUI48,OUI,EUI64)...exceptValueErroraserror:...print(error)...'01:23'cannotbeparsedasEUI48,OUI,orEUI64Note that the message of theValueErrortries 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 BytesAllmacaddressclasses 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, aValueErroris raised:>>>try:...macaddress.MAC(b'\x01\x02\x03')...exceptValueErroraserror:...print(error)...b'\x01\x02\x03'haswronglengthforEUI48Parse from IntegersAllmacaddressclasses 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, aValueErroris raised:>>>try:...macaddress.OUI(1_000_000_000)...exceptValueErroraserror:...print(error)...1000000000istoobigforOUIGet 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:>>>classMAC(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)==0x010203040506TrueGet the OUIMost classes supplied by this module have theouiattribute, which returns their first three bytes as
an OUI object:>>>macaddress.MAC('01:02:03:04:05:06').ouiOUI('01-02-03')CompareEqualityAllmacaddressclasses 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').ouiFalseOrderingAllmacaddressclasses 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'),...]>>>forxinsorted(some_values):...print(x)FF-EE-00-99-88-77FF-EE-DDFF-EE-DD-01-02-03FF-EE-DD-01-02-04Define New TypesIf 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:classInfiniBand(macaddress.HWAddress):size=20*8# size in bits; 20 octetsformats=('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.