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 }