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. C99 port
* (canonical TS: src/lib/mac-generator.ts; Go twin: cli/mac-address-generator).
* Octets come from rand() seeded once (the TS default draws from
* crypto.getRandomValues; C99 has no portable crypto source). %02x pairs are
* sprintf'd into a caller buffer, joined with the separator. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct {
const char *separator; /* NULL -> ":" */
int uppercase;
const char *oui; /* NULL or "" -> random OUI octets */
int locally_administered; /* force U/L bit (0x02) of the first octet */
} MacOptions;
/* Strip non-hex chars, require exactly 6 digits, parse the 3 OUI octets. */
static int parse_oui(const char *oui, unsigned char out[3]) {
char clean[8] = {0};
int n = 0;
for (const char *p = oui; *p; p++)
if (isxdigit((unsigned char)*p)) {
if (n == 6) return 0; /* too many hex digits */
clean[n++] = *p;
}
if (n != 6) return 0;
for (int i = 0; i < 3; i++) {
char pair[3] = { clean[i * 2], clean[i * 2 + 1], 0 };
out[i] = (unsigned char)strtoul(pair, NULL, 16);
}
return 1;
}
/* 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. out must hold
* 12 hex digits + 5 separators + 1 NUL. */
static void generate_mac(const MacOptions *o, char *out) {
unsigned char oct[6];
if (o->oui && *o->oui) {
if (!parse_oui(o->oui, oct)) {
fprintf(stderr, "OUI must be 6 hex digits, got \"%s\"\n", o->oui);
exit(1);
}
} else {
for (int i = 0; i < 3; i++) oct[i] = (unsigned char)(rand() & 0xFF);
}
for (int i = 3; i < 6; i++) oct[i] = (unsigned char)(rand() & 0xFF);
if (o->locally_administered) oct[0] = (unsigned char)((oct[0] & 0xFD) | 0x02);
const char *sep = o->separator ? o->separator : ":";
char *w = out;
for (int i = 0; i < 6; i++) {
if (i) w += sprintf(w, "%s", sep);
w += sprintf(w, "%02x", oct[i]);
}
if (o->uppercase)
for (char *p = out; *p; p++) *p = (char)toupper((unsigned char)*p);
}
int main(void) {
srand(42); /* demo seed */
char mac[64];
generate_mac(&(MacOptions){0}, mac), puts(mac); /* 6 random hex pairs */
generate_mac(&(MacOptions){.separator = "-"}, mac), puts(mac);
generate_mac(&(MacOptions){.oui = "aa-bb-cc"}, mac), puts(mac); /* aa:bb:cc:xx:xx:xx */
generate_mac(&(MacOptions){.locally_administered = 1, .uppercase = 1}, mac), puts(mac); /* first pair ends in 2 */
return 0;
}
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 →