在物联网开发中,随机数生成是一个常见的需求。无论是用于安全加密、数据模拟还是游戏开发,随机数都能发挥重要作用。本文将介绍如何在低功耗Air780E模组上使用LuatOS操作系统生成随机数,并通过示例代码展示具体实现方法。
一、随机数概述
随机数是专门的随机试验的结果. 在统计学的不同技术中需要使用随机数,比如在从统计总体中抽取有代表性的样本的时候,或者在将实验动物分配到不同的试验组的过程中,或者在进行蒙特卡罗模拟法计算的时候等等. 产生随机数有多种不同的方法.这些方法被称为随机数生成器.随机数最重要的特性是它在产生时后面的那个数与前面的那个数毫无关系.
根据密码学原理,随机数的随机性检验可以分为三个标准:
1.统计学伪随机性.统计学伪随机性指的是在给定的随机比特流样本中,1的数量大致等于0的数量,同理,“10”“01”“00”“11”四者数量大致相等.类似的标准被称为统计学随机性.满足这类要求的数字在人类“一眼看上去”是随机的.
2.密码学安全伪随机性.其定义为,给定随机样本的一部分和随机算法,不能有效的演算出随机样本的剩余部分.
3.真随机性.其定义为随机样本不可重现.实际上只要给定边界条件,真随机数并不存在,可是如果产生一个真随机数样本的边界条件十分复杂且难以捕捉(比如计算机当地的本底辐射波动值),可以认为用这个方法演算出来了真随机数.
相应的,随机数也分为三类:
1.伪随机数:满足第一个条件的随机数.
2.密码学安全的伪随机数:同时满足前两个条件的随机数.可以通过密码学安全伪随机数生成器计算得出.
3.真随机数:同时满足三个条件的随机数.
我们知道,随机数是通过一些复杂的数学算法得到的,那么 随机种子就是这些随机数的初始值.
一般计算机里面产生的随机数都是伪随机数. 伪随机数,也是就一个一直不变的数,所以我们可以通过输入随机种子得到一个初始固定的随机数.
例如,随机数的种子设置为x,产生的随机数序列为: [123, 456,789,...],那么只要输入相同的随机种子x,就能得到相同的随机数序列:[123, 456,789,...],否则就无法还原出随机数序列,也就无法通过密码学安全的随机数生成器计算出随机数序列.
二、演示功能概述
本文章通过 Air780 的核心板烧录底层固件(LuatOS-SoC_V1112_EC618_FULL.soc)和修改 LuatOS 示例代码(点此链接查看 crypto 的 demo 例子),来演示有关随机数的各种 API 的功能.
三、硬件准备
3.1 Air780E 核心板
使用 Air780E 核心板,如下图所示:
3.2 SIM 卡
中国大陆环境下,可以上网的 sim 卡,一般来说,使用移动,电信,联通的物联网卡或者手机卡都行。
3.3 PC 电脑
请准备一台配备 USB 接口且能够正常上网的电脑
电脑操作系统为:WIN10以及以上版本的WINDOWS系统
3.4 数据通信线
带TYPE-C口的USB数据线
四、软件环境
4.1 Luatools 工具
要想烧录 LuatOS 固件到 4G 模组中,需要用到强大的调试工具:Luatools
详细使用说明参考:Luatools 工具使用说明: https://docs.openluat.com/Luatools/
Luatools 工具集具备以下几大核心功能:
一键获取最新固件:自动连接服务器,轻松下载最新的模组固件.
固件与脚本烧录:便捷地将固件及脚本文件烧录至目标模组中.
串口日志管理:实时查看模组通过串口输出的日志信息,并支持保存功能.
串口调试助手:提供简洁的串口调试界面,满足基本的串口通信测试需求.
Luatools 下载之后,新建一个命名为 "Luatools" 的文件夹,将下载的Luatools_v3.exe拷贝或移动到新建的Luatools文件夹内,点击 Luatools_v3.exe 即可运行.
4.2 准备需要烧录的代码
首先要说明一点: 脚本代码, 要和固件的 soc 文件一起烧录.
4.2.1 烧录的底层固件文件
底层 core 下载地址:LuatOS 固件版本下载地址
https://docs.openluat.com/air780e/luatos/firmware/
Air780E 的底层固件在 Luatools 解压后目录的 LuatOS-SoC_V1112_EC618_FULL.soc
4.2.2 烧录的脚本代码
首先要下载 Air780 的 LuatOS 示例代码到一个合适的项目目录,示例代码网站: https://gitee.com/openLuat/LuatOS-Air780E
下载流程参考下图:
下载的文件解压,找到 LuatOS-Air780E-master\demo\crypto\main.lua,
如图:
正确连接电脑和 4G 模组电路板
使用带有数据通信功能的数据线,不要使用仅有充电功能的数据线;
识别 4G 模组的 BOOT 引脚
在下载之前,要用模组的 BOOT 引脚触发下载, 也就是说,要把 4G 模组的 BOOT 引脚拉到 1.8v,或者直接把 BOOT 引脚和 VDD_EXT 引脚相连.我们要在按下 BOOT 按键时让模块开机,就可以进入下载模式了.
具体到 Air780E 开发板:
1、当我们模块没开机时,按着 BOOT 键然后长按 POW 开机.
2、当我们模块开机时,按着 BOOT 键然后点按重启键即可.
识别电脑的正确端口
判断是否进入 BOOT 模式:模块上电,此时在电脑的设备管理器中,查看串口设备, 会出现一个端口表示进入了 BOOT 下载模式,如下图所示:
新建项目
首先,确保你的 Luatools 的版本,大于等于 3.0.6 版本的.
在 Luatools 的左上角上有版本显示的,如图所示:
Luatools 版本没问题的话, 就点击 LuaTools 右上角的“项目管理测试”按钮,如下图所示:
这时会弹出项目管理和烧录管理的对话框,可以新建一个项目,如下图:
开始烧录
选择 Air780E 板子对应的底层 core 和刚改的 main.lua 脚本文件.下载到板子中.
点击下载后,我们需要进入 BOOT 模式才能正常下载.
如果没进入 BOOT 模式会出现下图情况:
进入 BOOT 模式下载,如图:
五、API 说明
5.1 crypto.trng(len)
生成真随机数
参数
返回值
例子
5.2 math.random([n [,m]])
生成伪随机数
参数
返回值
例子
5.3 math.randomseed(n)
用法:设置一个整数 n 作为随机序列的种子.
参数
返回值
无
例子
六、功能演示
6.1 修改示例
首先找到 LuatOS-Air780E-master\demo\crypto\main.lua 脚本文件,复制一份 main.lua 文件到任意目录,我复制到 D:\Desktop\LuatOS-Air780E-master\random 这个目录
然后修改代码:
6.2 烧录固件
6.2.1 正确连接电脑和 4G 模组电路板
使用带有数据通信功能的数据线,不要使用仅有充电功能的数据线.
6.2.2 识别 4G 模组的 BOOT 引脚
在下载之前,要用模组的 BOOT 引脚触发下载, 也就是说,要把 4G 模组的 BOOT 引脚拉到 1.8v,或者直接把 BOOT 引脚和 VDD_EXT 引脚相连.我们要在按下 BOOT 按键时让模块开机,就可以进入下载模式了.
具体到 Air780E 开发板:
1、当我们模块没开机时,按着 BOOT 键然后长按 PWR 开机.
2、当我们模块开机时,按着 BOOT 键然后点按重启键即可.
6.2.3 识别电脑的正确端口
判断是否进入 BOOT 模式:模块上电,此时在电脑的设备管理器中,查看串口设备, 会出现一个端口表示进入了 BOOT 下载模式,如下图所示:
一旦进入了boot下载模式,表示硬件连接上已经处于就绪状态,此时就可以使用Luatools工具进行烧录了!
6.2.4 用 Luatools 工具烧录
新建项目
首先,确保你的 Luatools 的版本,大于等于 3.0.6 版本的.
在 Luatools 的左上角上有版本显示的,如图所示:
Luatools 版本没问题的话, 就点击 LuaTOols 右上角的“项目管理测试”按钮,如下图所示:
这时会弹出项目管理和烧录管理的对话框,可以新建一个项目,如下图:
开始烧录
选择 Air780E 板子对应的底层 core 和刚改的 main.lua 脚本文件.下载到板子中.
点击下载后,我们需要进入 BOOT 模式才能正常下载.
如果没进入 BOOT 模式会出现下图情况:
进入 BOOT 模式下载,如图:
6.3 对应 Log
七、总结
通过本章内容的学习,你可以学习到有关随机数的函数,例如: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()作为种子是一个简单而有效的方法:
然而,如果程序在很短的时间内多次运行,可能会发现生成的随机数序列几乎不变.这是因为os.time()返回的是秒级的时间戳,不够精确.为了解决这个问题,可以将时间戳转换为字符串,然后反转并截取高位数字作为种子:
这种方法通过提高种子数值的变化量,使得即使在短时间内多次运行程序,也能产生更好的伪随机序列.