在Lua中,通常使用math.random & math.randomseed生成随机值和/或字符串,其中os.time用于math.randomseed。
然而,这种方法有一个主要缺点:返回的数总是和当前的时间一样随机,和每个随机数的间隔是1秒,如果一个人在很短的时间内需要很多随机值,那就太长了。
Lua用户wiki:http://lua-users.org/wiki/MathLibraryTutorial甚至指出了这个问题,并指出了相应的RandomStringS receipe:http://lua-users.org/wiki/RandomStrings。
所以我坐下来写了一种不同的算法(如果可以这样的话),它使用表的内存地址生成随机数:
math.randomseed(os.time())
function realrandom(maxlen)
local tbl = {}
local num = tonumber(string.sub(tostring(tbl), 8))
if maxlen ~= nil then
num = num % maxlen
end
return num
end
function string.random(length,pattern)
local length = length or 11
local pattern = pattern or '%a%d'
local rand = ""
local allchars = ""
for loop=0, 255 do
allchars = allchars .. string.char(loop)
end
local str=string.gsub(allchars, '[^'..pattern..']','')
while string.len(rand) ~= length do
local randidx = realrandom(string.len(str))
local randbyte = string.byte(str, randidx)
rand = rand .. string.char(randbyte)
end
return rand
end一开始,一切看起来都是随机的,我相信它们是.至少现在的计划是这样。
我的问题是,realrandom返回的这些数字有多大的随机性?
或者,是否有更好的方法在短于1秒的时间内生成随机数(如上面所解释的那样,哪种方式意味着不应该使用os.time ),而不依赖外部库,如果可能的话,使用完全跨平台的方式?
编辑:
对于RNG的种子方式,似乎存在一个重大的误解;在生产代码中,对math.randomseed()的调用只发生一次,这只是一个错误的例子。
我所说的随机值是每秒随机一次,很容易通过下面的粘贴来演示:http://codepad.org/4cDsTpcD。
由于这个问题将被否决,无论我的编辑,我也取消了我以前接受的答案-希望一个更好的答案,即使只是更好的意见。我知道关于随机值/数字的问题以前已经讨论过很多次了,但我没有发现这样一个问题可能与Lua相关--请记住这一点!
发布于 2011-02-17 23:14:44
lrandom模块(可在LuaRocks中获得)。/dev/random中读取。(我认为Windows应该有类似的东西--但您可能需要用C语言编写代码才能使用它。)socket.gettime()来自LuaSocket。将其乘以某个值,因为math.randomseed只处理整数部分,而socket.gettime()以(浮点)秒为单位返回时间。
要求‘套接字’math.randomseed(socket.gettime() * 1e6)为i= 1,1e3为打印(math.random())端发布于 2011-02-18 12:39:15
然而,这种方法有一个主要缺点:返回的数总是和当前时间一样随机,每个随机数的间隔是1秒,如果一个人在很短的时间内需要许多随机值,那么这个间隔就太长了。
只有当你不正确地实现它时,它才有这些弱点。
math.randomseed应该被谨慎地调用--通常在程序开始时只调用一次,并且它通常是使用os.time的种子。一旦设置了种子,您就可以多次使用math.random,它将产生随机值。
看看这个示例发生了什么:
> math.randomseed(1)
> return math.random(), math.random(), math.random()
0.84018771715471 0.39438292681909 0.78309922375861
> math.randomseed(2)
> return math.random(), math.random(), math.random()
0.70097636929759 0.80967634907443 0.088795455214007
> math.randomseed(1)
> return math.random(), math.random(), math.random()
0.84018771715471 0.39438292681909 0.78309922375861当我把种子从1变2时,我得到了不同的随机结果。但当我回到1,“随机序列”被重置。我得到了和以前一样的值。
os.time()返回一个不断增加的数字。使用它作为种子是合适的;然后您可以永远调用math.random,并且每次调用它时都有不同的随机数。
唯一需要担心非随机性的情况是,程序应该每秒执行不止一次。在这种情况下,正如其他人所说,最简单的解决方案是使用一个定义更高的时钟。
换言之:
os.time()在99%的情况下)调用os.time()math.random。致以问候!
发布于 2011-02-17 22:27:38
我想到了几件重要的事情:
如果您需要更多信息,请从维基百科的PRNG文章开始,并根据需要使用那里的参考资料/链接。
https://stackoverflow.com/questions/5035229
复制相似问题