// Package mac 设备码 MAC 编解码。 // // 布局:mac[0..1] = productid(16 位),mac[2..5] = 产品级全局序号(32 位)。 // 与授权码(utils/license)共用同一套「productid + 产品级序号」语义,不再编入生产批次。 package mac import ( "fmt" "strconv" "strings" ) // Generate 生成设备 MAC 地址(带冒号大写十六进制)。 // productid 占前 2 字节,serial(产品级全局序号)占后 4 字节。 func Generate(productid uint16, serial uint32) string { return fmt.Sprintf("%02X:%02X:%02X:%02X:%02X:%02X", byte(productid>>8), byte(productid), byte(serial>>24), byte(serial>>16), byte(serial>>8), byte(serial)) } // Parse 解析设备 MAC,返回 productid 与产品级序号。接受带冒号或不带冒号两种格式。 func Parse(macCode string) (productid uint16, serial uint32, err error) { s := strings.ReplaceAll(macCode, ":", "") if len(s) != 12 { return 0, 0, fmt.Errorf("MAC地址长度错误,期望12字符,实际%d字符", len(s)) } b := make([]byte, 6) for i := 0; i < 6; i++ { v, perr := strconv.ParseUint(s[i*2:i*2+2], 16, 8) if perr != nil { return 0, 0, fmt.Errorf("解析第%d字节失败: %v", i+1, perr) } b[i] = byte(v) } productid = uint16(b[0])<<8 | uint16(b[1]) serial = uint32(b[2])<<24 | uint32(b[3])<<16 | uint32(b[4])<<8 | uint32(b[5]) return }