0

I've tried searching for help but I haven't found a solution yet, I'm trying to repeat math.random.

current code:

local ok = ""
for i = 0,10 do
local ok = ok..math.random(0,10)
end
print(ok)

no clue why it doesn't work, please help

Wolf
  • 9,679
  • 7
  • 62
  • 108
  • Why are you trying to repeat a random number? What is the logic you are aiming for? – tomerpacific Jan 31 '21 at 10:52
  • Please explain what you expect that code to do, otherwise we won't be able to help – DarkWiiPlayer Jan 31 '21 at 10:55
  • 3
    Replace `local ok = ok..math.random` with `ok = ok..math.random` – Egor Skriptunoff Jan 31 '21 at 10:58
  • @tomerpacific I'm attempting to generate something like this: "%32%35%34"(etc.) to make it harder to find the full url of the link I'm hiding, and to make it harder generate some fake parts of the url encoding to make it harder to crack, so I'd want it to repeat %3 + random number from 0 to 9. – user14923496 Jan 31 '21 at 10:59

2 Answers2

1

Long answer

Even if the preferable answer is already given, just copying it will probably not lead to the solution you may expect or less future mistakes. So I decided to explain why your code fails and to fix it and also help better understand how DarkWiiPlayer's answer works (except for string.rep and string.gsub).

Issues

There are at least three issues in your code:

  1. the math.random(m, n) function includes lower and the upper values
  2. local declarations hide a same-name objects in outer scopes
  3. math.random gives the same number sequence unless you set its seed with math.randomseed

See Detailed explanation section below for more.

Another point seems at least worth mentioning or suspicious to me, as I assume you might be puzzled by the result (it seems to me to reflect exactly the perspective of the C programmer, from which I also got to know Lua): the Lua for loop specifies start and end value, so both of these values are included.

Attempt to repair

Here I show how a version of your code that yields the same results as the answer you accepted: a sequence of 10 percent-encoded decimal digits.

-- this will change the seed value (but mind that its resolution is seconds)
math.randomseed(os.time())

-- initiate the (only) local variable we are working on later
local ok = ""

-- encode 10 random decimals (Lua's for-loop is one-based and inclusive)
for i = 1, 10 do
  ok = ok .. 
    -- add fixed part
    '%3' .. 
    -- concatenation operator implicitly converts number to string
    math.random(0, 9) -- a random number in range [0..9]
end

print(ok)

Detailed explanation

This explanation makes heavily use of the assert function instead of adding print calls or comment what the output should be. In my opinion assert is the superior choice for illustrating expected behavior: The function guides us from one true statement - assert(true) - to the next, at the first miss - assert(false) - the program is exited.

Random ranges

The math library in Lua provides actually three random functions depending on the count of arguments you pass to it. Without arguments, the result is in the interval [0,1):

assert(math.random() >= 0)
assert(math.random() < 1)

the one-argument version returns a value between 1 and the argument:

assert(math.random(1) == 1)
assert(math.random(10) >= 1)
assert(math.random(10) <= 10)

the two-argument version explicitly specifies min and max values:

assert(math.random(2,2) == 2)
assert(math.random(0, 9) >= 0)
assert(math.random(0, 9) <= 9)

Hidden outer variable

In this example, we have two variables x of different type, the outer x is not accessible from the inner scope.

local x = ''
assert(type(x) == 'string')

do 
  local x = 0
  assert(type(x) == 'number')
  -- inner x changes type
  x = x .. x
  assert(x == '00')
end

assert(type(x) == 'string')

Predictable randomness

The first call to math.random() in a Lua program will return always the same number because the pseudorandom number generator (PRNG) starts at seed 1. So if you call math.randomseed(1), you'll reset the PRNG to its initial state.

r0 = math.random()
math.randomseed(1)
r1 = math.random()
assert(r0 == r1)

After calling math.randomseed(os.time()) calls to math.random() will return different sequences presuming that subsequent program starts differ at least by one second. See question Current time in milliseconds and its answers for more information about the resolutions of several Lua functions.

Wolf
  • 9,679
  • 7
  • 62
  • 108
0
string.rep(".", 10):gsub(".", function() return "%3" .. math.random(0, 9) end)

That should give you what you want

DarkWiiPlayer
  • 6,871
  • 3
  • 23
  • 38