-2

I tried to remove the integer from the generated string with regex but this will not give me the length within the range required( many will be less than the minimum )

package main

import (
    "fmt"
    "log"
    "math/rand"
    "regexp"
    "time"
)

func randomString(length int) string {
    rand.Seed(time.Now().UnixNano())
    b := make([]byte, length)
    rand.Read(b)
    return fmt.Sprintf("%x", b)[:length]
}
func randomLength(minL, maxL int) int {
    rand.Seed(time.Now().UnixNano())

    return rand.Intn(maxL-minL) + minL
}

func main() {
    reg, err := regexp.Compile("[^a-zA-Z]+")
    if err != nil {
        log.Fatal(err)
    }

    for i := 0; i < 10; i++ {
        processedString := reg.ReplaceAllString(randomString(randomLength(8, 16)), "")
        println(processedString)

    }

}

Edit: when I searched for the question I missed detailed @icza answer in that question.

MSH
  • 395
  • 1
  • 4
  • 13
  • 4
    Either don't use random bytes but only a charset that excludes digit, or iterate over the result and replace digits with random, allowed chars. Also: you do know you're generating hex representation of random bytes right? If so, you could just use the first 16 letters of the English alphabet to represent hex digits. Also: you don't need to call `rand.Seed()` every time, just once, in `main()` or in a package `init()`. – icza Mar 15 '22 at 18:09
  • thanks, @icza, I forget about the `rand.Seed()` but I did not understand what is **hex representation of random bytes** is there a link for that, please. – MSH Mar 15 '22 at 19:08
  • 1
    This `fmt.Sprintf("%x", b)` will transform `b` into a hex representation, using characters in the range of `['0'..'9']` and `['a'..'f']`. These are the hex digits. You could use the first 16 letters of the English alphabet instead of these hex digits, it would also be enough to replace `['0'..'9']` with letters `['g'..'p']`. – icza Mar 15 '22 at 19:22
  • 2
    But again, it's easier to just choose random chars from the allowed range and not go through these transformations. See [How to generate a random string of a fixed length in Go?](https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go/31832326#31832326) Also by transforming bytes to hex, you double the length and risk of being longer than `maxL`. – icza Mar 15 '22 at 19:22

2 Answers2

3
var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))

func StringWithCharset(length int, charset string) string {
    b := make([]byte, length)
    for i := range b {
        b[i] = charset[seededRand.Intn(len(charset)-1)]
    }
    return string(b)
}

func main() {
    rangeStart := 0
    rangeEnd := 10
    offset := rangeEnd - rangeStart
    randLength := seededRand.Intn(offset) + rangeStart

    charSet := "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"
    randString := StringWithCharset(randLength, charSet)
}
Colin F
  • 31
  • 2
  • thanks a lot the logic is right but can you made some correction please so It will be buildable . like `b[i] = charset[seededRand.Intn(len(charset)-1)]` , `charSet := "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"` , `randString = StringWithCharset(randLength, charSet)` , `var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))` – MSH Mar 15 '22 at 19:16
  • 1
    thanks, should be buildable – Colin F Mar 15 '22 at 19:29
1

You just need to define the alphabet that you're using. Something like the following (You can fiddle with it here in the Go Playground).

package main

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

func main() {

  rand.Seed(time.Now().UnixNano())

  var alphabet []rune = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")

  rs := randomString(20, alphabet)
  fmt.Printf("This is pretty random: %s\n", rs)

}

func randomString(n int, alphabet []rune) string {

  alphabetSize := len(alphabet)
  var sb strings.Builder

  for i := 0; i < n; i++ {
    ch := alphabet[rand.Intn(alphabetSize)]
    sb.WriteRune(ch)
  }

  s := sb.String()
  return s
}
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135