Files
order_site/apps/dcauth/base32.go
T
yml2213 040100f290 feat(dcauth): 新增后台手机号与设备认证登录
登录链路改为账号密码 + 短信验证码 + DCAuth 设备签名,并新增后台手机号绑定、
登录日志、设备绑定与重置接口。
2026-10-21 20:46:24 +08:00

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
}