package main import ( "crypto/sha256" "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 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() }