lua - (安全)随机字符串?

标签 lua

在 Lua 中,通常会使用 math.random 生成随机值和/或字符串。 & math.randomseed , 其中 os.time用于 math.randomseed .

然而,这种方法有一个主要缺点。返回的数字总是与当前时间一样随机,每个随机数的间隔为一秒,如果在很短的时间内需要许多随机值,这太长了。

Lua 用户 wiki 甚至指出了这个问题:http://lua-users.org/wiki/MathLibraryTutorial ,以及对应的 RandomStringS 收据: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 返回的这些数字有多随机?真的吗?

或者有没有更好的方法在比一秒更短的时间间隔内生成随机数(这意味着不应该使用 os.time,如上所述),而不依赖于外部库,并且,如果可能的话,在完全跨平台的方式?

编辑:
似乎对 RNG 的播种方式存在重大误解;在生产代码中,调用 math.randomseed()只发生一次,这只是一个选择不当的例子。

我所说的随机值是每秒随机一次,这个粘贴很容易证明:http://codepad.org/4cDsTpcD

由于无论我的编辑如何,这个问题都会被否决,因此我还取消了我之前接受的答案——希望得到一个更好的答案,即使只是更好的意见。我知道关于随机值/数字的问题之前已经讨论过很多次了,但是我没有发现这样一个可能与 Lua 相关的问题 - 请记住这一点!

最佳答案

  • 每次调用随机时都不应该调用种子 ,你应该只调用一次,在程序初始化时(除非你从某个地方得到种子,例如,复制一些以前的“随机”行为)。
  • 标准 Lua 随机生成器在统计意义上的质量很差(事实上,它是标准 C 随机生成器),如果您关心它,请不要使用它。例如,使用 lrandom模块(在 LuaRocks 中可用)。
  • 如果您需要更安全的随机数,请阅读 /dev/random在 Linux 上。 (我认为 Windows 应该有一些类似的东西——但你可能需要用 C 编写一些代码才能使用它。)
  • 依赖表指针值是个坏主意。想想替代的 Lua 实现,例如在 Java 中——不知道它们会返回什么。 (此外,指针值可能是可预测的,并且在某些情况下,每次调用程序时它们可能是相同的。)
  • 如果您希望种子具有更高的精度(并且只有在 启动程序 的频率超过每秒一次时才需要),您应该使用分辨率更高的计时器。例如,socket.gettime()来自 LuaSocket。将它乘以某个值,因为 math.randomseed仅使用整数部分,socket.gettime()以(浮点)秒为单位返回时间。
    require 'socket'
    
    math.randomseed(socket.gettime() * 1e6)
    
    for i = 1, 1e3 do
      print(math.random())
    end
    
  • 关于lua - (安全)随机字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5035229/

    相关文章:

    datetime - os.difftime(t2, t1) 的用途是什么,但 t2 - t1 未涵盖?

    function - 让Lua打印(functionname.variable)

    带参数的 Redis StackExchange LuaScripts

    lua - 恢复到旧版本的 Lua?

    string - 使用 string.match 处理语音标记

    c++ - 将纯lua对象传递给C函数并获取值

    lua - 调用 String.pack 返回未找到 pack 方法

    iphone - 计算圆形 wrapper ?

    lua - 在 Lua 中实现延迟执行?

    lua中的正则表达式模式问题