package shorturl import ( "crypto/rand" "fmt" "math/big" "regexp" ) // CodeLength is the length of generated short codes. 10 base36 characters // give 36^10 ≈ 3.6 × 10^15 combinations. const CodeLength = 10 // codeAlphabet is the base36 alphabet (lowercase letters + digits). const codeAlphabet = "abcdefghijklmnopqrstuvwxyz0123456789" var codeAlphabetBig = big.NewInt(int64(len(codeAlphabet))) // RandomCode returns a cryptographically random base36 code of CodeLength chars. func RandomCode() (string, error) { buf := make([]byte, CodeLength) for i := range buf { n, err := rand.Int(rand.Reader, codeAlphabetBig) if err != nil { return "", fmt.Errorf("random code: %w", err) } buf[i] = codeAlphabet[n.Int64()] } return string(buf), nil } var validCodeRe = regexp.MustCompile(`^[a-z0-9]{4,16}$`) // ValidCode returns true if s could plausibly be a short code we issued. // Lenient on length (4-16) to allow future tuning without breaking old links. func ValidCode(s string) bool { return validCodeRe.MatchString(s) }