DEV Community

Samy
Samy

Posted on

How to tell if a MAC address is randomized

Your phone probably isn't using its real MAC address on your Wi-Fi. Since iOS 14 and Android 10, phones use a private, random MAC for each Wi-Fi network by default, and Windows 10 and 11 offer the same as a setting. That's good for privacy, but it breaks anything that relies on "MAC address = device": DHCP reservations, captive portals, asset inventories and parental controls.

Here's how to spot a randomized MAC, with one rule and a few lines of code.

The one bit that matters

Every MAC address is 6 bytes. The first byte holds two flag bits:

  • Bit 0 (I/G): 1 means multicast, 0 means unicast.
  • Bit 1 (U/L): 1 means locally administered, 0 means universally administered, which means assigned by the IEEE to a manufacturer.

A manufacturer-assigned MAC always has the U/L bit set to 0. Random MACs set it to 1, because they're generated by the device's software, not burned in at the factory.

The shortcut: look at the second hex character. If it's 2, 6, A or E, the address is locally administered.

3C:22:FB:12:34:56  -> second char C -> universally administered (Apple, Inc.)
DA:A1:19:5B:22:07  -> second char A -> locally administered, likely random
Enter fullscreen mode Exit fullscreen mode

In Python

def is_locally_administered(mac: str) -> bool:
    first_octet = int(mac.replace("-", ":").split(":")[0], 16)
    return bool(first_octet & 0b10)

def is_multicast(mac: str) -> bool:
    first_octet = int(mac.replace("-", ":").split(":")[0], 16)
    return bool(first_octet & 0b01)

print(is_locally_administered("DA:A1:19:5B:22:07"))  # True
print(is_locally_administered("3C:22:FB:12:34:56"))  # False
Enter fullscreen mode Exit fullscreen mode

"Locally administered" is not the same as "random"

Virtual machines, Docker bridges, VPN adapters and some enterprise gear also use locally administered addresses on purpose. IEEE 802c split the local address space into four quadrants (the SLAP), so some locally administered addresses are structured rather than random. So the honest answer is "probably randomized", not "definitely".

Getting the vendor for real MACs

If the U/L bit is 0, the first 3 bytes (the OUI) identify the manufacturer. You can look it up with a free endpoint that needs no API key:

curl https://api.macadress.com/v1/vendor/3C:22:FB:12:34:56
# Apple, Inc.
Enter fullscreen mode Exit fullscreen mode
import requests

def vendor(mac: str) -> str:
    r = requests.get(f"https://api.macadress.com/v1/vendor/{mac}", timeout=5)
    return r.text if r.ok else "unknown"
Enter fullscreen mode Exit fullscreen mode

For a random MAC there's no vendor to find, which is itself a strong hint. If you'd rather not write the logic yourself, macadress.com shows the block type, country and a plain-English randomization verdict for any address. There's a longer write-up on how MAC randomization works.

Takeaways

  • Second hex digit 2/6/A/E means locally administered.
  • Locally administered plus no vendor match means probably random.
  • Don't build identity or security decisions on MAC addresses alone.

Top comments (0)