MAC Address Generator — C++ source
Generate random EUI-48 MAC addresses with a chosen separator, optional OUI prefix, uppercase formatting, and a locally-administered flag. Runs entirely in your browser with crypto-grade randomness.
This is the C++ implementation — the same logic the interactive tool runs, in a shareable, citable form.
// mac-address-generator — random EUI-48 MAC address generator. C++20 port
// (canonical TS: src/lib/mac-generator.ts; Go twin: cli/mac-address-generator).
// The default rng draws from mt19937_64 seeded by random_device (the TS lib
// uses crypto.getRandomValues); the showcase keeps the rng injectable
// (std::function returning [0, 1)) so the demo asserts exact MAC strings.
#include <cctype>
#include <iostream>
#include <functional>
#include <iomanip>
#include <random>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
struct MacOptions {
std::string separator = ":"; // empty string concatenates
bool uppercase = false;
std::string oui; // empty -> random OUI octets
bool locally_administered = false; // force U/L bit (0x02) of the first octet
std::function<double()> rng = [] {
static std::mt19937_64 gen{std::random_device{}()};
return std::uniform_real_distribution<double>(0.0, 1.0)(gen);
};
};
// Strip non-hex chars, require exactly 6 digits, parse the 3 OUI octets.
static std::vector<int> parse_oui(const std::string &oui) {
std::string clean;
for (char c : oui)
if (std::isxdigit(static_cast<unsigned char>(c))) clean += c;
if (clean.size() != 6)
throw std::invalid_argument("OUI must be 6 hex digits, got \"" + oui + "\"");
return {std::stoi(clean.substr(0, 2), nullptr, 16),
std::stoi(clean.substr(2, 2), nullptr, 16),
std::stoi(clean.substr(4, 2), nullptr, 16)};
}
// Build a random EUI-48 MAC: 3 OUI octets (given or random) + 3 random,
// U/L bit forced when asked, joined as %02x with the separator.
std::string generate_mac(MacOptions o = {}) {
std::vector<int> oct = o.oui.empty() ? std::vector<int>{} : parse_oui(o.oui);
for (int i = 0; i < (o.oui.empty() ? 6 : 3); i++) oct.push_back(int(o.rng() * 256));
if (o.locally_administered) oct[0] = (oct[0] & 0xFD) | 0x02;
std::ostringstream ss;
for (size_t i = 0; i < oct.size(); i++) {
if (i) ss << o.separator;
ss << std::hex << std::setfill('0') << std::setw(2) << oct[i];
}
std::string mac = ss.str();
if (o.uppercase)
for (char &c : mac) c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
return mac;
}
int main() {
std::cout << generate_mac({.rng = [] { return 0.0; }}) << "\n"; // 00:00:00:00:00:00
std::cout << generate_mac({.separator = "-"}) << "\n"; // 6 random pairs, dash-joined
std::cout << generate_mac({.rng = [] { return 0.7; }, .uppercase = true}) << "\n"; // B3:B3:B3:B3:B3:B3
std::cout << generate_mac({.rng = [] { return 0.0; }, .oui = "aa-bb-cc"}) << "\n"; // aa:bb:cc:00:00:00
std::cout << generate_mac({.rng = [] { return 0.5; }, .locally_administered = true}) << "\n"; // 82:80:80:80:80:80
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →