随机数(random)
一、随机数概述
随机数是专门的随机试验的结果. 在统计学的不同技术中需要使用随机数,比如在从统计总体中抽取有代表性的样本的时候,或者在将实验动物分配到不同的试验组的过程中,或者在进行蒙特卡罗模拟法计算的时候等等. 产生随机数有多种不同的方法.这些方法被称为随机数生成器.随机数最重要的特性是它在产生时后面的那个数与前面的那个数毫无关系.
根据密码学原理,随机数的随机性检验可以分为三个标准:
1.统计学伪随机性.统计学伪随机性指的是在给定的随机比特流样本中,1的数量大致等于0的数量,同理,“10”“01”“00”“11”四者数量大致相等.类似的标准被称为统计学随机性.满足这类要求的数字在人类“一眼看上去”是随机的.
2.密码学安全伪随机性.其定义为,给定随机样本的一部分和随机算法,不能有效的演算出随机样本的剩余部分.
3.真随机性.其定义为随机样本不可重现.实际上只要给定边界条件,真随机数并不存在,可是如果产生一个真随机数样本的边界条件十分复杂且难以捕捉(比如计算机当地的本底辐射波动值),可以认为用这个方法演算出来了真随机数.
相应的,随机数也分为三类:
1.伪随机数:满足第一个条件的随机数.
2.密码学安全的伪随机数:同时满足前两个条件的随机数.可以通过密码学安全伪随机数生成器计算得出.
3.真随机数:同时满足三个条件的随机数.
我们知道,随机数是通过一些复杂的数学算法得到的,那么 随机种子就是这些随机数的初始值.
一般计算机里面产生的随机数都是伪随机数. 伪随机数,也是就一个一直不变的数,所以我们可以通过输入随机种子得到一个初始固定的随机数.
例如,随机数的种子设置为x,产生的随机数序列为: [123, 456,789,...],那么只要输入相同的随机种子x,就能得到相同的随机数序列:[123, 456,789,...],否则就无法还原出随机数序列,也就无法通过密码学安全的随机数生成器计算出随机数序列.
二、演示功能概述
本文章通过 Air780 的核心板烧录底层固件(LuatOS-SoC_V2002_Air780EP)和修改 LuatOS 示例代码(点此链接查看 crypto 的 demo 例子),来演示有关随机数的各种 API 的功能.
三、硬件准备
参考:硬件环境清单第二章节内容,准备以及组装好硬件环境。
四、软件环境
“凡事预则立,不预则废。”在详细阐述本功能示例之前,我们需先精心筹备好以下软件环境。
1. Luatools工具;
2. 内核固件文件(底层core固件文件):LuatOS-SoC_V2002_Air780EP;参考项目使用的内核固件;
3. luatos需要的脚本和资源文件
脚本和资源文件点击此处查看与下载
lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件;
准备好软件环境之后,接下来查看如何烧录项目文件到Air780EP核心板,将本篇文章中演示使用的项目文件烧录到Air780EP核心板中。
五、API 说明
5.1 crypto.trng(len)
生成真随机数
参数
传入值类型 | 解释 |
---|---|
int | 数据长度 |
返回值
返回值类型 | 解释 |
---|---|
string | 指定随机数字符串 |
例子
-- 生成 32 位随机数 ir
local r = crypto.trng(4)
local _, ir = pack.unpack(r, "I")
5.2 math.random([n [,m]])
生成伪随机数
参数
传入值类型 | 解释 |
---|---|
int | 生成随机数范围 |
int | 生成随机数范围 |
返回值
返回值类型 | 解释 |
---|---|
local | 随机数字 |
例子
--无参调用,产生[0, 1)之间的浮点随机数.
local num = math.random()
--一个参数 n,产生[1, n]之间的整数
local num = math.random(n)
--两个参数,产生[n, m]之间的整数.
local num = math.random(n,m)
5.3 math.randomseed(n)
用法:设置一个整数 n 作为随机序列的种子.
参数
传入值类型 | 解释 |
---|---|
int | 种子数据 |
返回值
无
例子
--得到了正常的随机数
math.randomseed(os.time())
for i=0, 10 do
local n = math.random(10)
end
--一系列相同的数,这种在一个 for 循环内设置随机数的写法 seed 几乎是一样导致.
for i=0, 10 do
math.randomseed(os.time())
local n = math.random(10)
end
六、功能演示
6.1 修改示例
首先找到 LuatOS-Air780EP-master\demo\crypto\main.lua 脚本文件,复制一份 main.lua 文件到任意目录,我复制到 D:\Desktop\LuatOS-Air780EP-master\random 这个目录
然后修改代码:
PROJECT = "cryptodemo"
VERSION = "1.0.0"
-- sys库是标配
_G.sys = require("sys")
sys.taskInit(function()
sys.wait(1000)
-- ---------------------------------------
log.info("随机数测试")
math.randomseed(os.time())
for i=1, 10 do
sys.wait(100)
log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
log.info("crypto", "伪随机数",math.random(100)) --输出1-100之间随机数
log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
end
log.info("crypto", "ALL Done")
sys.wait(100000)
end)
sys.run()
对应 Log
[2024-10-18 15:30:52.567] 工具提示: soc log port COM5打开成功
[2024-10-18 15:30:52.595] 工具提示: ap log port COM6打开成功
[2024-10-18 15:30:52.598] 工具提示: 用户虚拟串口 COM9
[2024-10-18 15:30:52.677] 工具提示: 用户log保存在D:\Desktop\LuaTools\log\trace_2024-10-18_153052.txt 如果有问题交给FAE
[2024-10-18 15:30:52.676][000000000.009] am_service_init 851:Air780EP_A17
[2024-10-18 15:30:52.686][000000000.023] Uart_BaseInitEx 1049:uart 0 rx cache 256 dma 256
[2024-10-18 15:30:52.687][000000000.225] self_info 122:model Air780EP_A17 imei 868327075469021
[2024-10-18 15:30:52.688][000000000.227] I/pm poweron: Power/Reset
[2024-10-18 15:30:52.689][000000000.227] I/main LuatOS@EC618 base 23.11 bsp V1112 32bit
[2024-10-18 15:30:52.690][000000000.227] I/main ROM Build: Sep 3 2024 15:55:27
[2024-10-18 15:30:52.691][000000000.235] D/main loadlibs luavm 262136 14360 14392
[2024-10-18 15:30:52.692][000000000.235] D/main loadlibs sys 277872 53984 81264
[2024-10-18 15:30:52.694][000000000.246] I/user.main cryptodemo 1.0.0
[2024-10-18 15:30:53.486][000000001.276] I/user.随机数测试
[2024-10-18 15:30:53.596][000000001.386] I/user.crypto 真随机数 -2126957010 5
[2024-10-18 15:30:53.607][000000001.388] I/user.crypto 伪随机数 0.4636298
[2024-10-18 15:30:53.611][000000001.389] I/user.crypto 伪随机数 50
[2024-10-18 15:30:53.613][000000001.390] I/user.crypto 伪随机数 46998
[2024-10-18 15:30:53.690][000000001.491] I/user.crypto 真随机数 -309051301 5
[2024-10-18 15:30:53.693][000000001.492] I/user.crypto 伪随机数 0.6394390
[2024-10-18 15:30:53.706][000000001.501] I/user.crypto 伪随机数 10
[2024-10-18 15:30:53.714][000000001.502] I/user.crypto 伪随机数 38883
[2024-10-18 15:30:53.802][000000001.604] I/user.crypto 真随机数 -1863938574 5
[2024-10-18 15:30:53.805][000000001.605] I/user.crypto 伪随机数 0.9536643
[2024-10-18 15:30:53.807][000000001.607] I/user.crypto 伪随机数 25
[2024-10-18 15:30:53.811][000000001.608] I/user.crypto 伪随机数 16512
[2024-10-18 15:30:53.928][000000001.717] I/user.crypto 真随机数 1261760763 5
[2024-10-18 15:30:53.934][000000001.719] I/user.crypto 伪随机数 0.6245894
[2024-10-18 15:30:53.937][000000001.720] I/user.crypto 伪随机数 54
[2024-10-18 15:30:53.940][000000001.721] I/user.crypto 伪随机数 21478
[2024-10-18 15:30:54.023][000000001.822] I/user.crypto 真随机数 936401639 5
[2024-10-18 15:30:54.027][000000001.824] I/user.crypto 伪随机数 0.9050973
[2024-10-18 15:30:54.036][000000001.833] I/user.crypto 伪随机数 1
[2024-10-18 15:30:54.039][000000001.834] I/user.crypto 伪随机数 44043
[2024-10-18 15:30:54.148][000000001.936] I/user.crypto 真随机数 1715074597 5
[2024-10-18 15:30:54.156][000000001.937] I/user.crypto 伪随机数 0.5631961
[2024-10-18 15:30:54.159][000000001.938] I/user.crypto 伪随机数 10
[2024-10-18 15:30:54.161][000000001.939] I/user.crypto 伪随机数 13488
[2024-10-18 15:30:54.258][000000002.049] I/user.crypto 真随机数 -1914839329 5
[2024-10-18 15:30:54.269][000000002.050] I/user.crypto 伪随机数 0.7684302
[2024-10-18 15:30:54.272][000000002.051] I/user.crypto 伪随机数 77
[2024-10-18 15:30:54.274][000000002.052] I/user.crypto 伪随机数 30056
[2024-10-18 15:30:54.366][000000002.154] I/user.crypto 真随机数 -974370001 5
[2024-10-18 15:30:54.371][000000002.155] I/user.crypto 伪随机数 0.2707427
[2024-10-18 15:30:54.375][000000002.165] I/user.crypto 伪随机数 11
[2024-10-18 15:30:54.380][000000002.166] I/user.crypto 伪随机数 46138
[2024-10-18 15:30:54.475][000000002.267] I/user.crypto 真随机数 -1427124973 5
[2024-10-18 15:30:54.489][000000002.268] I/user.crypto 伪随机数 0.3834128
[2024-10-18 15:30:54.492][000000002.270] I/user.crypto 伪随机数 88
[2024-10-18 15:30:54.495][000000002.271] I/user.crypto 伪随机数 12880
[2024-10-18 15:30:54.584][000000002.381] I/user.crypto 真随机数 427995234 5
[2024-10-18 15:30:54.596][000000002.382] I/user.crypto 伪随机数 0.3756179
[2024-10-18 15:30:54.601][000000002.383] I/user.crypto 伪随机数 23
[2024-10-18 15:30:54.604][000000002.384] I/user.crypto 伪随机数 20818
[2024-10-18 15:30:54.607][000000002.385] I/user.crypto ALL Done
七、总结
通过本章内容的学习,你可以学习到有关随机数的函数,例如:crypto.trng(len)、math.random([n [,m]])、math.randomseed(n) 等函数.
八、扩展
8.1 注意事项
需要注意的是,Lua 中的随机数算法可能存在一些问题.例如,math.random(1, 3276700)返回的值最后两位必为 0,这是由于 Lua 本身的随机函数算法决定的.因此,在使用 Lua 生成随机数时,应当注意这些潜在的限制,并尽可能通过设置合适的随机种子来避免生成可预测的随机数序列.
通过以上方法,可以在 Lua 中有效地生成随机数,并确保每次运行程序时都能得到不同的随机数序列,从而满足各种需要随机性的应用场景.
8.2 设置随机数种子
为了确保每次运行程序时都能生成不同的随机数序列,需要使用math.randomseed来设置一个随机种子.通常,使用系统时间os.time()作为种子是一个简单而有效的方法:
math.randomseed(os.time())
math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 7)))
给读者的话
本篇文章由公帅开发;
本篇文章描述的内容,如果有错误、细节缺失、细节不清晰或者其他任何问题,总之就是无法解决您遇到的问题;
请登录合宙技术交流论坛,点击文档找错赢奖金-Air780EP-LuatOS-软件指南-基础服务-随机数(random);
用截图标注+文字描述的方式跟帖回复,记录清楚您发现的问题;
我们会迅速核实并且修改文档;
同时也会为您累计找错积分,您还可能赢取月度找错奖金!