package utilsx import ( "encoding/base64" "encoding/hex" "strings" "testing" ) func TestGenerateRandomString(t *testing.T) { // 测试生成随机字符串 str, err := GenerateRandomString(10) if err != nil { t.Errorf("生成随机字符串失败: %v", err) return } if len(str) != 10 { t.Errorf("生成的字符串长度不正确,期望: 10, 实际: %d", len(str)) } // 测试长度为0 _, err = GenerateRandomString(0) if err == nil { t.Errorf("长度为0应该返回错误") } // 测试多次生成,应该不同 str2, err := GenerateRandomString(10) if err != nil { t.Errorf("生成随机字符串失败: %v", err) return } if str == str2 { t.Errorf("多次生成的随机字符串应该不同") } } func TestGenerateRandomBytes(t *testing.T) { // 测试生成随机字节 bytes, err := GenerateRandomBytes(10) if err != nil { t.Errorf("生成随机字节失败: %v", err) return } if len(bytes) != 10 { t.Errorf("生成的字节长度不正确,期望: 10, 实际: %d", len(bytes)) } // 测试长度为0 _, err = GenerateRandomBytes(0) if err == nil { t.Errorf("长度为0应该返回错误") } // 测试多次生成,应该不同 bytes2, err := GenerateRandomBytes(10) if err != nil { t.Errorf("生成随机字节失败: %v", err) return } // 比较字节切片 equal := true for i := range bytes { if bytes[i] != bytes2[i] { equal = false break } } if equal { t.Errorf("多次生成的随机字节应该不同") } } func TestGenerateRandomHexString(t *testing.T) { // 测试生成随机十六进制字符串 hexStr, err := GenerateRandomHexString(10) if err != nil { t.Errorf("生成随机十六进制字符串失败: %v", err) return } // 十六进制字符串长度应该是字节长度的两倍 if len(hexStr) != 20 { t.Errorf("生成的十六进制字符串长度不正确,期望: 20, 实际: %d", len(hexStr)) } // 验证是否为有效的十六进制字符串 _, err = hex.DecodeString(hexStr) if err != nil { t.Errorf("生成的字符串不是有效的十六进制: %v", err) } // 测试多次生成,应该不同 hexStr2, err := GenerateRandomHexString(10) if err != nil { t.Errorf("生成随机十六进制字符串失败: %v", err) return } if hexStr == hexStr2 { t.Errorf("多次生成的随机十六进制字符串应该不同") } } func TestGenerateRandomBase64String(t *testing.T) { // 测试生成随机Base64字符串 base64Str, err := GenerateRandomBase64String(10) if err != nil { t.Errorf("生成随机Base64字符串失败: %v", err) return } // 验证是否为有效的Base64字符串 _, err = base64.StdEncoding.DecodeString(base64Str) if err != nil { t.Errorf("生成的字符串不是有效的Base64: %v", err) } // 测试多次生成,应该不同 base64Str2, err := GenerateRandomBase64String(10) if err != nil { t.Errorf("生成随机Base64字符串失败: %v", err) return } if base64Str == base64Str2 { t.Errorf("多次生成的随机Base64字符串应该不同") } } func TestCalculateHash(t *testing.T) { // 测试计算哈希 input := "test input" hash := CalculateHash(input) // SHA1哈希应该是40个字符 if len(hash) != 40 { t.Errorf("哈希长度不正确,期望: 40, 实际: %d", len(hash)) } // 相同输入应该产生相同哈希 hash2 := CalculateHash(input) if hash != hash2 { t.Errorf("相同输入产生了不同的哈希") } // 不同输入应该产生不同哈希 hash3 := CalculateHash("different input") if hash == hash3 { t.Errorf("不同输入产生了相同的哈希") } } func TestGenerateUUID(t *testing.T) { // 测试生成UUID uuid, err := GenerateUUID() if err != nil { t.Errorf("生成UUID失败: %v", err) return } // UUID应该是36个字符(包括4个连字符) if len(uuid) != 36 { t.Errorf("UUID长度不正确,期望: 36, 实际: %d", len(uuid)) } // UUID应该包含4个连字符 if strings.Count(uuid, "-") != 4 { t.Errorf("UUID应该包含4个连字符") } // 测试多次生成,应该不同 uuid2, err := GenerateUUID() if err != nil { t.Errorf("生成UUID失败: %v", err) return } if uuid == uuid2 { t.Errorf("多次生成的UUID应该不同") } } func TestGenerateAPIKey(t *testing.T) { // 测试生成API密钥(无前缀) apiKey, err := GenerateAPIKey("") if err != nil { t.Errorf("生成API密钥失败: %v", err) return } // 验证是否为有效的Base64 _, err = base64.StdEncoding.DecodeString(apiKey) if err != nil { t.Errorf("生成的API密钥不是有效的Base64: %v", err) } // 测试生成API密钥(有前缀) apiKeyWithPrefix, err := GenerateAPIKey("test") if err != nil { t.Errorf("生成API密钥失败: %v", err) return } // 应该包含前缀 if !strings.HasPrefix(apiKeyWithPrefix, "test.") { t.Errorf("API密钥应该包含前缀") } // 去掉前缀后应该是有效的Base64 parts := strings.Split(apiKeyWithPrefix, ".") if len(parts) != 2 { t.Errorf("API密钥格式不正确") return } _, err = base64.StdEncoding.DecodeString(parts[1]) if err != nil { t.Errorf("生成的API密钥不是有效的Base64: %v", err) } // 测试多次生成,应该不同 apiKey2, err := GenerateAPIKey("") if err != nil { t.Errorf("生成API密钥失败: %v", err) return } if apiKey == apiKey2 { t.Errorf("多次生成的API密钥应该不同") } } func TestGenerateToken(t *testing.T) { // 测试生成令牌 token, err := GenerateToken(20) if err != nil { t.Errorf("生成令牌失败: %v", err) return } if len(token) != 20 { t.Errorf("令牌长度不正确,期望: 20, 实际: %d", len(token)) } // 令牌应该不包含填充字符 if strings.Contains(token, "=") { t.Errorf("令牌不应该包含填充字符") } // 测试长度为0 _, err = GenerateToken(0) if err == nil { t.Errorf("长度为0应该返回错误") } // 测试多次生成,应该不同 token2, err := GenerateToken(20) if err != nil { t.Errorf("生成令牌失败: %v", err) return } if token == token2 { t.Errorf("多次生成的令牌应该不同") } } func TestGeneratePassword(t *testing.T) { // 测试生成密码(所有字符类型) password, err := GeneratePassword(12, true, true, true, true) if err != nil { t.Errorf("生成密码失败: %v", err) return } if len(password) != 12 { t.Errorf("密码长度不正确,期望: 12, 实际: %d", len(password)) } // 测试只使用大写字母 passwordUpper, err := GeneratePassword(10, true, false, false, false) if err != nil { t.Errorf("生成密码失败: %v", err) return } // 验证只包含大写字母 for _, c := range passwordUpper { if !(c >= 'A' && c <= 'Z') { t.Errorf("密码包含非大写字母字符: %c", c) } } // 测试只使用小写字母 passwordLower, err := GeneratePassword(10, false, true, false, false) if err != nil { t.Errorf("生成密码失败: %v", err) return } // 验证只包含小写字母 for _, c := range passwordLower { if !(c >= 'a' && c <= 'z') { t.Errorf("密码包含非小写字母字符: %c", c) } } // 测试只使用数字 passwordDigits, err := GeneratePassword(10, false, false, true, false) if err != nil { t.Errorf("生成密码失败: %v", err) return } // 验证只包含数字 for _, c := range passwordDigits { if !(c >= '0' && c <= '9') { t.Errorf("密码包含非数字字符: %c", c) } } // 测试长度为0 _, err = GeneratePassword(0, true, true, true, true) if err == nil { t.Errorf("长度为0应该返回错误") } // 测试不选择任何字符类型 _, err = GeneratePassword(10, false, false, false, false) if err == nil { t.Errorf("不选择任何字符类型应该返回错误") } } func TestHashPassword(t *testing.T) { // 测试哈希密码 password := "test_password" salt := "test_salt" hash := HashPassword(password, salt) // SHA1哈希应该是40个字符 if len(hash) != 40 { t.Errorf("哈希长度不正确,期望: 40, 实际: %d", len(hash)) } // 相同密码和盐应该产生相同哈希 hash2 := HashPassword(password, salt) if hash != hash2 { t.Errorf("相同密码和盐产生了不同的哈希") } // 不同盐应该产生不同哈希 hash3 := HashPassword(password, "different_salt") if hash == hash3 { t.Errorf("不同盐产生了相同的哈希") } // 不同密码应该产生不同哈希 hash4 := HashPassword("different_password", salt) if hash == hash4 { t.Errorf("不同密码产生了相同的哈希") } } func TestVerifyPassword(t *testing.T) { // 测试验证密码 password := "test_password" salt := "test_salt" // 正确的密码应该验证通过 hash := HashPassword(password, salt) if !VerifyPassword(password, salt, hash) { t.Errorf("正确的密码验证失败") } // 错误的密码应该验证失败 if VerifyPassword("wrong_password", salt, hash) { t.Errorf("错误的密码验证通过") } // 错误的盐应该验证失败 if VerifyPassword(password, "wrong_salt", hash) { t.Errorf("错误的盐验证通过") } } // 基准测试 func BenchmarkGenerateRandomString(b *testing.B) { for i := 0; i < b.N; i++ { GenerateRandomString(16) } } func BenchmarkGenerateRandomBytes(b *testing.B) { for i := 0; i < b.N; i++ { GenerateRandomBytes(16) } } func BenchmarkCalculateHash(b *testing.B) { input := "benchmark test string" for i := 0; i < b.N; i++ { CalculateHash(input) } } func BenchmarkGenerateUUID(b *testing.B) { for i := 0; i < b.N; i++ { GenerateUUID() } } func BenchmarkGenerateAPIKey(b *testing.B) { for i := 0; i < b.N; i++ { GenerateAPIKey("") } } func BenchmarkGenerateToken(b *testing.B) { for i := 0; i < b.N; i++ { GenerateToken(32) } } func BenchmarkGeneratePassword(b *testing.B) { for i := 0; i < b.N; i++ { GeneratePassword(16, true, true, true, true) } } func BenchmarkHashPassword(b *testing.B) { password := "benchmark_password" salt := "benchmark_salt" for i := 0; i < b.N; i++ { HashPassword(password, salt) } }