欢迎回到我们用 Go 构建密码管理器的旅程!在第二部分中,我们将探讨自初次提交以来我们所取得的进展。我们添加了新功能,改进了代码结构并实施了测试。让我们潜入吧!
您会注意到的第一个变化是改进的项目结构。我们遵循 Go 的最佳实践,将代码分成多个文件和包:
dost/ . ├── LICENSE ├── README.md ├── go.mod ├── go.sum ├── internal │ ├── internal_test.go │ └── passgen.go └── main.go
随着我们项目的发展,这种结构可以实现更好的组织和可维护性。
我们显着改进了 CLI,使其更加灵活且用户友好。这是我们 main.go 的片段:
func main() { generateCmd := flag.NewFlagSet("generate", flag.ExitOnError) flag.Parse() switch os.Args[1] { case "generate": internal.Generate(generateCmd) } }
此设置允许使用子命令,目前支持生成命令。用户现在可以像这样与我们的工具交互:
go run main.go generate email/reachme@example.com 15
我们添加了自定义密码生成的选项。用户现在可以指定密码长度并选择排除特殊字符:
func Generate(generateFlags *flag.FlagSet) { generateFlags.BoolVar(&noSymbols, "n", false, "Skip symbols while generating password") generateFlags.BoolVar(©ToClipBoard, "c", false, "Copy to clipboard.") generateFlags.Parse(os.Args[2:]) passwordLength := 25 // ... (code to parse custom length) password, err := generatePassword(passwordLength, noSymbols) // ... (code to handle password output) }
此功能允许用户使用 -n 等标志来排除符号,使用 -c 将密码复制到剪贴板而不是显示它。
我们改进了密码生成功能以处理新的自定义选项:
func generatePassword(length int, noSymbols bool) (string, error) { const ( uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" lowercaseLetters = "abcdefghijklmnopqrstuvwxyz" digits = "0123456789" specialChars = "!@#$%^&*()-_=+[]{}|;:'\",.<>/?" ) allChars := uppercaseLetters + lowercaseLetters + digits if !noSymbols { allChars += specialChars } var password string for i := 0; i < length; i++ { // Generate a random index to select a character from allChars randomIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(allChars)))) if err != nil { return "", err } // Append the randomly selected character to the password password += string(allChars[randomIndex.Int64()]) } return password, nil }
此函数现在遵循 noSymbols 标志,允许更灵活的密码生成。
我们通过实施测试在确保代码可靠性方面迈出了重要一步。这是我们的测试文件的片段:
func TestPasswordLength(t *testing.T) { password, err := generatePassword(10, true) if err != nil { t.Errorf("Expected no error, got %v", err) } else { if len(password) != 10 { t.Errorf("Expected 10 character password, got %d", len(password)) } } } func TestSpecialCharacter10K(t *testing.T) { splCharMissing := 0 for i := 1; i <= 10000; i++ { password, err := generatePassword(10, false) // ... (code to check for special characters) } if splCharMissing > 0 { t.Errorf("Special character was missing in %d / 10000 instances.", splCharMissing) } }
这些测试检查密码长度是否正确以及是否包含特殊字符。有趣的是,我们的特殊字符测试揭示了一个需要改进的地方:在 10,000 个生成的密码中,有 234 个不包含特殊字符。这为我们下一步的改进提供了明确的方向。
虽然我们取得了重大进展,但仍有改进的空间:
请继续关注我们系列的下一部分,我们将解决这些挑战并继续改进我们的密码管理器!
请记住,完整的源代码可以在 GitHub 上找到。请随意克隆、分叉并为该项目做出贡献。随时欢迎您的反馈和贡献!
祝您编码愉快,并保持安全! ??
dost 是一个用 Go 编写的 CLI 密码管理器。
灵感来自(通行证)[https://www.passwordstore.org/]
> go build -o dost main.go
Generating password:
> ./dost generate email/vema@example.com Generated Password: );XE,7-Dv?)Aa+&<{V-|pKuq5
Generating password with specified length (default is 25):
> ./dost generate email/vema@example.com 12 Generated Password: si<yJ=5/lEb3
Copy generated password to clipboard without printing:
> ./dost generate -c email/vema@example.com Copied to clipboard! ✅
Avoid symbols for generating passwords:
> ./dost generate -n email/vema@example.com Generated Password: E2UST}^{Ac[Fb&D|cD%;Eij>H
MIT
以上是在 Go 中构建密码管理器:第 2 部分的详细内容。更多信息请关注PHP中文网其他相关文章!