🏆 Exercise: Secure Password Generation in Go

🎯 Objective :

In this exercise, you will build a Go program that generates secure passwords based on user-defined criteria. You'll use the new math/rand/v2package, which replaces the older math/rand, for modern and efficient random number generation.

📜 Problem Statement :

You need to implement a Go program that generates one or more passwords according to the following criteria :

🎯 Final Goal :

Your program should :

💡 Hints & Tips :

🧐 Code Explanation :

1️⃣ Character Set Definition :

The program definescharacter groupsto be used in passwords:


const (
	lettersUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	lettersLower = "abcdefghijklmnopqrstuvwxyz"
	digits       = "0123456789"
	specialChars = "!@#$%^&*()_+-=[]{}|;:'\",.<>?/"
)

                

🔹 The password will be built using these groups, depending on the chosen security level.

2️⃣ Password Generation Function :

The main function responsible for password creation :

func generatePassword(length int, level string) string
                

This function :

3️⃣ Why math/rand/v2?

math/rand/v2is a modern and improved version of math/rand. It provides :

In this code, we use rand.NewPCG(seed, seed+1), which is more reliable than the traditional math/rand.Seed().

4️⃣ User Input Handling in main() :

The main()function :

✅ Complete Solution :


package main

import (
	"fmt"
	"math/rand/v2"
	"strings"
	"time"
)

// Character sets definition
const (
	lettersUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	lettersLower = "abcdefghijklmnopqrstuvwxyz"
	digits       = "0123456789"
	specialChars = "!@#$%^&*()_+-=[]{}|;:'\",.<>?/"
)

// Function to generate a secure password
func generatePassword(length int, level string) string {
	var charSet string

	// Select character set based on security level
	switch level {
	case "weak":
		charSet = lettersUpper + lettersLower
	case "medium":
		charSet = lettersUpper + lettersLower + digits
	case "strong":
		charSet = lettersUpper + lettersLower + digits + specialChars
	default:
		fmt.Println("Invalid security level. Choose: weak, medium, or strong.")
		return ""
	}

	// Validate password length
	if length < 8 || length > 32 {
		fmt.Println("Invalid length. Choose between 8 and 32 characters.")
		return ""
	}

	// Initialize a unique random seed
	seed := uint64(time.Now().UnixNano() + int64(rand.IntN(1000000))) // Unique seed
	rng := rand.New(rand.NewPCG(seed, seed+1))

	// Generate the password
	var password strings.Builder
	for i := 0; i < length; i++ {
		password.WriteByte(charSet[rng.IntN(len(charSet))])
	}

	return password.String()
}

// Main function
func main() {
	var length int
	var level string
	var numPasswords int

	// User input
	fmt.Print("Enter password length (8-32): ")
	fmt.Scan(&length)

	fmt.Print("Enter security level (weak, medium, strong): ")
	fmt.Scan(&level)

	fmt.Print("How many passwords do you want to generate? ")
	fmt.Scan(&numPasswords)

	// Generate and display passwords
	fmt.Println("\nGenerated Passwords:")
	for i := 0; i < numPasswords; i++ {
		password := generatePassword(length, strings.ToLower(level))
		if password != "" {
			fmt.Printf("[%d] %s\n", i+1, password)
		}
	}
}

                

📚 Further Learning Resources :

📌 Official Go Documentation (math/rand/v2) : 🔗 https://pkg.go.dev/math/rand/v2

📌 Best Practices for Secure Passwords : 🔗 https://www.ncsc.gov.uk/collection/passwords

🚀 Thank you for working through these exercises! If you find this content valuable and want to support my work, a coffee would be greatly appreciated! ☕😊

💻 I am a freelance web developer, and I personally create and maintain this website. Any support would help me improve and expand it further! 🙌


☕ Buy me a coffee