这段代码能够被反向工程找到随机种子吗?

local digits = {'1', '2', '3', '4', '5', '6', '8', '9'}
math.randomseed(os.time())
local result = digits[math.random(8)]
for i = 2, 50 do
    result = result..digits[math.random(8)]
end
print(result)

--> 88854243421464255299891111895292628431988589634664

这是一段 Lua 脚本,用于输出 50 个随机数字,不包括 0 和 7。我似乎找不到 Lua 随机算法。是否可能找到由 os.time() 返回的值?

用通俗的语言来说,这是脚本的工作方式:

  1. 定义一个包含八个单字符字符串的列表。
  2. 将伪随机算法种子设置为自 1970 年 1 月 1 日午夜以来的秒数。
  3. 使用伪随机算法选择介于 1 和 8 之间的数字,然后用该数字从列表中选择一个项目。例如,选择的数字是 7,算法会选择列表中的第 7 个项目。
  4. 将该项目添加到结果的末尾。重复操作,直到结果达到 50 位数字长。

因此,由于 7 被省略,随机算法确实发出了这个结果:

77754243421464255288781111785282627431877578634664

但由于 7 被省略了,所以 7 和 8 变成了 8 和 9,得出了以下结果:

88854243421464255299891111895292628431988589634664

为了澄清,我正在尝试弄清楚随机算法是如何工作的,以找到输入的随机种子。

同样在这里询问:https://forum.roblox.com/Forum/ShowPost.aspx?PostID=215349554 以及在这里:https://scriptinghelpers.org/questions/42360/can-this-script-be-reverse-engineered-to-find-the-random-seed 还有这里:https://crypto.stackexchange.com/questions/47027/can-this-code-be-reverse-engineered-to-find-the-random-seed

点赞
用户1816580
用户1816580

这段代码能否被逆向工程用来找到随机种子?

也许可以,也许不行。这取决于math.random的实现。

是否有可能找到os.time()返回的值?

当然可以。os.time()被定义为

当不带参数调用time函数时,它将当前日期和时间编码为一个数字返回。(在大多数系统中,该数字是距离某个历元的秒数。)

我们说的是32位整数。这可以很容易地被暴力破解。您甚至可以假设一些边界条件。这可能是在最近一个月左右生成的,因此无需搜索在未来的种子。过去30天中只有22位不同的秒。

您可以简单地通过从现在到以前迭代种子,并每次生成50位数的随机值。然后您只需要将其与您拥有的一个进行比较,找到匹配项并停止搜索。此过程不应花费超过一分钟。

以下是全部代码:

function GetDigits(t)
    local digits = {'1', '2', '3', '4', '5', '6', '8', '9'}
    math.randomseed(t)
    local result = digits[math.random(8)]
    for i = 2, 50 do
        result = result..digits[math.random(8)]
    end
    return result
end

ct = os.time()
while ct > 1 do
    if ct % 100000 == 0 then
        print (ct)
    end
    if GetDigits(ct) == "88854243421464255299891111895292628431988589634664" then
        print ("found: " .. ct)
        break
    end
    ct = ct - 1
end

输出结果:

1493400000
1493300000
1493200000
1493100000
1493000000
1492900000
1492800000
1492700000
1492600000
1492500000
1492400000
1492300000
1492200000
1492100000
1492000000
1491900000
1491800000
1491700000
1491600000
1491500000
found: 1491404649

这只适用于Lua v5.1,因为实现在v5.2v5.3中已更改。我只在Windows上尝试过。

2017-04-29 07:58:59
用户5287638
用户5287638

这并不是一个完整的回答,但是它可能会帮助你入门。你可以在这里找到 Lua 的 math.random 函数的 C 源代码(这是 Lua 5.1 的,但其他版本类似)。Lua 并不尝试自己生成伪随机数,而是将这个任务外包给 C 标准库。

具体来说,math.random 使用 C 的 rand 函数生成数字,而 math.randomseed 使用 C 的 srand 函数(在与 rand 相同的 man 手册中介绍)设置伪随机数生成器的种子。这些函数在每个系统上实现方式不同(例如 x86 Windows 版本与 x86 Linux 版本不同,不同芯片组会有不同版本等等),因此您需要分析您感兴趣的每个系统的算法。

关于 rand 的实现方式,这个问题应该能帮你入门。

你一定要小心的是,如果有人能猜到你调用 os.time 的秒数(或者他们恰好在同一时间调用了它),那么他们可以通过将该值传递给 math.randomseed 来生成完全相同的伪随机数。如果您有一个更高熵的种子可用,最好使用它。

2017-04-29 08:47:46