2025-10-01 16:30:27 +00:00
|
|
|
package usecase
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"math/big"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ErrInvalidDigits is returned when the number of digits is invalid
|
|
|
|
var ErrInvalidDigits = errors.New("invalid number of digits")
|
|
|
|
|
|
|
|
// generateVerifyCode generates a cryptographically secure verification code.
|
|
|
|
// The digits parameter specifies the number of digits in the code (4-10).
|
|
|
|
// If digits is 0 or negative, it defaults to 6 digits.
|
|
|
|
func generateVerifyCode(digits int) (string, error) {
|
|
|
|
// Default to 6 digits if not specified or invalid
|
|
|
|
if digits <= 0 {
|
|
|
|
digits = 6
|
|
|
|
}
|
2025-10-02 06:43:57 +00:00
|
|
|
|
2025-10-01 16:30:27 +00:00
|
|
|
// Validate digit range
|
|
|
|
if digits < 4 || digits > 10 {
|
|
|
|
return "", fmt.Errorf("%w: digits must be between 4 and 10, got %d", ErrInvalidDigits, digits)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate maximum value (10^digits - 1)
|
|
|
|
exp := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(digits)), nil)
|
2025-10-02 06:43:57 +00:00
|
|
|
|
2025-10-01 16:30:27 +00:00
|
|
|
// Generate cryptographically secure random number
|
|
|
|
randomNumber, err := rand.Int(rand.Reader, exp)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("failed to generate random number: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert to string with zero padding
|
|
|
|
verifyCode := fmt.Sprintf("%0*d", digits, randomNumber)
|
2025-10-02 06:43:57 +00:00
|
|
|
|
2025-10-01 16:30:27 +00:00
|
|
|
return verifyCode, nil
|
|
|
|
}
|