Feedback on my random string generator

This is my first post on the developer forum, so sorry if formatting isn’t great. Alright, so I was really bored so I decided to make something new, I came up with a random string generator. It supports any symbol, letter, number, pretty much everything. If someone could look over it and give some feedback or explain maybe a better way to do this that would be much appreciated, thanks!

function GenString()

local validchars = {"q","w","e","r","t","y","u","i","o","p","a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m","1","2","3","4","5","6","7","8","9","0","X","A","B","V","R","I","O","P","L"}

local Gen = nil

Gen = validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.random(1,#validchars)]..validchars[math.rando m(1,#validchars)]..validchars[math.random(1,#validchars)]

return Gen

end



local str = GenString()

print(str)

Thank you!

1 Like

You might find it easier if you use ASCII codes. It’s already sort of there with your table, but it’d be cleaner & easier to add more stuff into it.

I’m not sure on all of them, but I know a bit of it, like:
A-Z is represented as the range from 65 to 90
a-z is 97 to 122
There’s a range for all the numbers

Etc. You can look up an ASCII table to get the codes & use the string.byte() and string.char() functions to encode/decode that

2 Likes

First off, nitpicking. Indentation - use it and you’ll thank yourself later. Case - use camelCase for your function and variable names (i.e. genString() rather than GenString(), gen instead of Gen, validChars instead of validchars), as this helps code readability and consistency.

Second off, the way you’re generating Gen is what’s known as “hard-coded”. If you wanted to create a string of length 2057, you’d have to write out ..validchars[math.random(1,#validchars)] 2057 times, which is incredibly inefficient. Look into using for loops:

However, since you are creating Gen the way you are, you don’t need to declare it as equal to nil - it would be declared automatically when you assigned your value to it.

Finally, you don’t need to store the value of GenString() into the variable str, you can simply do print(GenString())

1 Like

Personally I’d implement it like this.

local valid_chars = {}

local function set_valid(x, y)
    for i = string.byte(x), string.byte(y) do
        table.insert(valid_chars, string.char(i))
    end
end

local function random_string(length)
    local s = {}

    for i = 1, length do s[i] = valid_chars[math.random(1, #valid_chars)] end

    return table.concat(s)
end

set_valid('a', 'z')
set_valid('A', 'Z')
set_valid('0', '9')

print(random_string(5))

You can rely on ASCII guarantees such as a<z and A<Z to iterate from one end to the other and get all the characters in between to quickly fill your table. set_valid just does this loop from character to character to populate the table of valid characters, which only needs to be done once.

For generating a random string, it’s bad practice and memory intensive to concatenate a large amount of unknown substrings together into a large one iteratively, so making a buffer table serves better. Once you have your table, you just loop for the length of your desired random string and set the indices to a random character from the valid array. Once you are done, call table.concat, which takes the values in an array and concatenates them all in 1 go to avoid the problem of reallocating every time.

Also it’s good to note that you should initialize all your variables you plan on reusing without mutating outside the functions that use them. That way, you only need to make a valid_chars array once as opposed to every call of the function like in your example.

11 Likes

Make a for loop. It would clean up the code a little bit:

local chars = {...}
local str = ""

for i = 1, 16 do
    str = str .. chars[math.random(1, #chars)]
end

print(str)

Change 16 to whatever length of string you want, then you don’t have to manually add characters to the string.

6 Likes