90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
const crockfordAlphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
|
|
|
|
func buildDeviceID(publicKey []byte) string {
|
|
material := append([]byte("dcauth.device.v1"), publicKey...)
|
|
sum := sha256.Sum256(material)
|
|
return formatCode("D1", sum[:])
|
|
}
|
|
|
|
func buildMachineCode() (string, error) {
|
|
components, err := collectHardwareComponents()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
keys := make([]string, 0, len(components))
|
|
for key := range components {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
parts := []string{"dcauth.machine.v1"}
|
|
for _, key := range keys {
|
|
parts = append(parts, key+"="+components[key])
|
|
}
|
|
sum := sha256.Sum256([]byte(strings.Join(parts, "\n")))
|
|
return formatCode("M1", sum[:]), nil
|
|
}
|
|
|
|
func formatCode(prefix string, data []byte) string {
|
|
encoded := base32Crockford(data)
|
|
if len(encoded) > 20 {
|
|
encoded = encoded[:20]
|
|
}
|
|
groups := make([]string, 0, 5)
|
|
for len(encoded) > 0 {
|
|
size := 4
|
|
if len(encoded) < size {
|
|
size = len(encoded)
|
|
}
|
|
groups = append(groups, encoded[:size])
|
|
encoded = encoded[size:]
|
|
}
|
|
return prefix + "-" + strings.Join(groups, "-")
|
|
}
|
|
|
|
func base32Crockford(data []byte) string {
|
|
var builder strings.Builder
|
|
var buffer uint32
|
|
var bits uint
|
|
for _, value := range data {
|
|
buffer = (buffer << 8) | uint32(value)
|
|
bits += 8
|
|
for bits >= 5 {
|
|
bits -= 5
|
|
builder.WriteByte(crockfordAlphabet[(buffer>>bits)&31])
|
|
}
|
|
}
|
|
if bits > 0 {
|
|
builder.WriteByte(crockfordAlphabet[(buffer<<(5-bits))&31])
|
|
}
|
|
return builder.String()
|
|
}
|
|
|
|
func normalizeComponent(value string) string {
|
|
normalized := strings.ToUpper(strings.TrimSpace(value))
|
|
normalized = strings.Join(strings.Fields(normalized), "")
|
|
switch normalized {
|
|
case "", "0", "NONE", "N/A", "NA", "UNKNOWN", "DEFAULTSTRING",
|
|
"TOBEFILLEDBYO.E.M.", "TOBEFILLEDBYOEM", "SYSTEMSERIALNUMBER",
|
|
"00000000-0000-0000-0000-000000000000":
|
|
return ""
|
|
}
|
|
return normalized
|
|
}
|
|
|
|
func ensureNotEmpty(components map[string]string) error {
|
|
if len(components) == 0 {
|
|
return fmt.Errorf("无法读取本机硬件信息,请联系管理员")
|
|
}
|
|
return nil
|
|
}
|