You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
44 lines
1.7 KiB
44 lines
1.7 KiB
// Package mac 设备码 MAC 编解码。
|
|
//
|
|
// 布局:mac[0..1] = productid(16 位),mac[2..5] = 产品级全局序号(32 位)。
|
|
//
|
|
// **MAC 就是设备码**:2026-09-02 起 license_<pid> 分表的主键 code 直接存 MAC,
|
|
// 原先那套 20 字符的授权码字符串(utils/license)已整体移除。产品、生产批次、
|
|
// 渠道商全都能从 MAC 查回来——PID 直接编在前 2 字节里,批次与渠道存在这一行上。
|
|
//
|
|
// ⚠️ productid 占 16 位,取值必须 ≤ 0xFFFF:调用方传的是 uint16,
|
|
// 更大的 PID 会被静默截断,两款产品能算出一模一样的 MAC。
|
|
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
|
|
}
|
|
|