| package config |
|
|
| import "strings" |
|
|
| |
| |
| func NormalizeMobileForStorage(raw string) string { |
| digits, hasPlus := extractMobileDigits(raw) |
| if digits == "" { |
| return "" |
| } |
| if hasPlus { |
| return "+" + digits |
| } |
| if isChinaMobileWithCountryCode(digits) { |
| return "+86" + digits[2:] |
| } |
| if isChinaMainlandMobileDigits(digits) { |
| return "+86" + digits |
| } |
| |
| return "+" + digits |
| } |
|
|
| |
| func CanonicalMobileKey(raw string) string { |
| return NormalizeMobileForStorage(raw) |
| } |
|
|
| func extractMobileDigits(raw string) (digits string, hasPlus bool) { |
| s := strings.TrimSpace(raw) |
| if s == "" { |
| return "", false |
| } |
|
|
| for _, r := range s { |
| switch { |
| case r >= '0' && r <= '9': |
| goto collect |
| case isMobileSeparator(r): |
| continue |
| case r == '+': |
| hasPlus = true |
| goto collect |
| default: |
| goto collect |
| } |
| } |
|
|
| collect: |
| var b strings.Builder |
| b.Grow(len(s)) |
| for _, r := range s { |
| if r >= '0' && r <= '9' { |
| b.WriteRune(r) |
| } |
| } |
| return b.String(), hasPlus |
| } |
|
|
| func isChinaMainlandMobileDigits(digits string) bool { |
| if len(digits) != 11 || digits[0] != '1' { |
| return false |
| } |
| return digits[1] >= '3' && digits[1] <= '9' |
| } |
|
|
| func isChinaMobileWithCountryCode(digits string) bool { |
| if len(digits) != 13 || !strings.HasPrefix(digits, "86") { |
| return false |
| } |
| return isChinaMainlandMobileDigits(digits[2:]) |
| } |
|
|
| func isMobileSeparator(r rune) bool { |
| switch r { |
| case ' ', '\t', '\n', '\r', '-', '(', ')', '.', '/': |
| return true |
| default: |
| return false |
| } |
| } |
|
|