diff --git a/service/address.go b/service/address.go index 57d8e81..adba4aa 100644 --- a/service/address.go +++ b/service/address.go @@ -5,6 +5,8 @@ import ( "net" "net/url" "strings" + + "git.apinb.com/bsm-sdk/core/utils" ) type NetworkAddress struct { @@ -126,28 +128,24 @@ func determineTCPProtocol(host string) string { // 解析传统格式如 ":8080", "127.0.0.1:8080", "/tmp/socket" func parseTraditionalStyle(addr string) (*NetworkAddress, error) { - result := &NetworkAddress{Raw: addr} - // 检查是否是 Unix socket(包含路径分隔符) if strings.Contains(addr, "/") || strings.HasPrefix(addr, "@/") { - result.Protocol = "unix" - result.Path = addr - return result, nil + return &NetworkAddress{Protocol: "unix", Path: addr}, nil } // 否则按 TCP 地址解析 - result.Protocol = "tcp" - host, port, err := net.SplitHostPort(addr) - if err != nil { - return nil, fmt.Errorf("解析地址失败: %w", err) + if err == nil { + return &NetworkAddress{Protocol: "tcp", Host: host, Port: port}, nil } - result.Host = host - result.Port = port - result.Protocol = determineTCPProtocol(host) + // 检查是否是端口号 + if ok := utils.IsNumber(addr); ok { + return &NetworkAddress{Protocol: "tcp", Host: "0.0.0.0", Port: addr}, nil + } + + return nil, fmt.Errorf("解析地址失败: %w", err) - return result, nil } // 获取网络类型用于 net.Dial 或 net.Listen diff --git a/utils/validator.go b/utils/validator.go new file mode 100644 index 0000000..3b716e6 --- /dev/null +++ b/utils/validator.go @@ -0,0 +1,129 @@ +package utils + +import ( + "regexp" + "strings" + "unicode" +) + +// IsEmail 验证是否是邮箱格式 +func IsEmail(email string) bool { + if strings.TrimSpace(email) == "" { + return false + } + + // 邮箱正则表达式 + pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` + matched, err := regexp.MatchString(pattern, email) + if err != nil { + return false + } + return matched +} + +// IsMobile 验证是否是手机号(中国手机号格式) +func IsMobile(mobile string) bool { + if strings.TrimSpace(mobile) == "" { + return false + } + + // 中国手机号正则表达式:1开头,第二位3-9,后面9位数字 + pattern := `^1[3-9]\d{9}$` + matched, err := regexp.MatchString(pattern, mobile) + if err != nil { + return false + } + return matched +} + +// IsNumber 验证是否是纯数字 +func IsNumber(str string) bool { + if strings.TrimSpace(str) == "" { + return false + } + + for _, char := range str { + if !unicode.IsDigit(char) { + return false + } + } + return true +} + +// IsEnglish 验证是否是英文字符(不限大小写) +func IsEnglish(str string) bool { + if strings.TrimSpace(str) == "" { + return false + } + + for _, char := range str { + if !unicode.IsLetter(char) { + return false + } + if !isEnglishLetter(char) { + return false + } + } + return true +} + +// IsEnglishWithSpace 验证是否是英文字符(允许空格) +func IsEnglishWithSpace(str string) bool { + if strings.TrimSpace(str) == "" { + return false + } + + for _, char := range str { + if unicode.IsSpace(char) { + continue + } + if !unicode.IsLetter(char) { + return false + } + if !isEnglishLetter(char) { + return false + } + } + return true +} + +// IsAlphanumeric 验证是否是字母和数字组合 +func IsAlphanumeric(str string) bool { + if strings.TrimSpace(str) == "" { + return false + } + + for _, char := range str { + if !unicode.IsLetter(char) && !unicode.IsDigit(char) { + return false + } + } + return true +} + +// IsStrongPassword 验证强密码(至少8位,包含大小写字母和数字) +func IsStrongPassword(password string) bool { + if len(password) < 8 { + return false + } + + var hasUpper, hasLower, hasDigit bool + + for _, char := range password { + switch { + case unicode.IsUpper(char): + hasUpper = true + case unicode.IsLower(char): + hasLower = true + case unicode.IsDigit(char): + hasDigit = true + } + } + + return hasUpper && hasLower && hasDigit +} + +// 辅助函数:判断是否是英文字母 +func isEnglishLetter(char rune) bool { + return (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') +}