Below is a simple Go example that generates MAC addresses with support for a custom prefix, control over the locally administered bit, and a configurable number of generated addresses.
The first byte is automatically normalized to ensure correct unicast behavior and optional local administration.
package main
import (
"fmt"
"math/rand"
"strconv"
"strings"
"time"
)
// normalizeFirstByte ensures the first byte has correct unicast and U/L bits
func normalizeFirstByte(b byte, locallyAdministered bool) byte {
// Clear I/G bit (bit 0) → unicast
b &= 0b11111110
// Set or clear U/L bit (bit 1)
if locallyAdministered {
b |= 0b00000010
} else {
b &= 0b11111101
}
return b
}
// generateMACAddresses generates MAC addresses with the given parameters
func generateMACAddresses(prefix string, locallyAdministered bool, count int) ([]string, error) {
// Initialize random seed
rand.Seed(time.Now().UnixNano())
// Normalize prefix - remove non-hex characters and convert to uppercase
hexPrefix := ""
for _, c := range strings.ToUpper(prefix) {
if (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') {
hexPrefix += string(c)
}
}
// Validate prefix length (max 5 bytes = 10 hex characters)
if len(hexPrefix)%2 != 0 || len(hexPrefix) > 10 {
return nil, fmt.Errorf("prefix must contain 0-5 bytes (0-10 hex characters)")
}
// Parse prefix bytes
var prefixBytes []byte
for i := 0; i < len(hexPrefix); i += 2 {
b, err := strconv.ParseUint(hexPrefix[i:i+2], 16, 8)
if err != nil {
return nil, fmt.Errorf("invalid hex in prefix: %v", err)
}
prefixBytes = append(prefixBytes, byte(b))
}
var macs []string
for i := 0; i < count; i++ {
// Start with prefix bytes
bytes := make([]byte, len(prefixBytes))
copy(bytes, prefixBytes)
// Generate remaining random bytes
for len(bytes) < 6 {
bytes = append(bytes, byte(rand.Intn(256)))
}
// Normalize first byte
bytes[0] = normalizeFirstByte(bytes[0], locallyAdministered)
// Format as MAC address
var parts []string
for _, b := range bytes {
parts = append(parts, fmt.Sprintf("%02X", b))
}
mac := strings.Join(parts, ":")
macs = append(macs, mac)
}
return macs, nil
}
func main() {
// Example usage
macs, err := generateMACAddresses(
"02:AB", // prefix
true, // locally administered
3, // count
)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
for _, mac := range macs {
fmt.Println(mac)
}
}