尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
NIST SP 800-22随机数测试工具完整指南:下载、编译、运行与结果解读
做密码、信息安全或者硬件安全的朋友应该都绕不开随机数这个东西。前阵子我评估一个硬件熵源模块的输出质量又把NIST随机数测试工具SP 800-22 Statistical Test Suite简称STS从下载到跑测试完整过了一遍。这套工具可以说是随机性验证领域的事实标准很多产品的检测报告、学术论文里的随机性验证用的都是它。但说实话官方文档写得比较学术网上的教程又零零散散很多细节要自己踩坑才能搞清楚。这篇文章我就把“目前最新”的NIST随机数测试软件的下载、安装、使用、结果解读全部串一遍尤其是数据格式、参数设置和那些容易翻车的地方给后面要做随机性验证的朋友当个参考。1. 认识NIST SP 800-22与随机性测试体系1.1 这个工具到底在测什么先纠正一个常见的理解偏差随机数测试软件并不能“证明”一串数据是随机的。它的逻辑是反过来的——通过一系列统计检验去发现数据中是否存在明显的规律、偏差或可预测性。如果能发现就说明这个随机数生成器RNG或PRNG的输出“不够随机”如果测不出问题只能说“没有发现不随机的证据”不能因此断定它绝对安全。SP 800-22这套工具的核心是15项统计测试每一项目标都不一样测试项主要检测目标频率测试Monobit全序列中0和1的比例是否接近1:1块内频率测试每个固定长度块内1的比例是否合理游程测试连续0或连续1的游程是否异常块内最长游程测试块内最长连续1序列是否在预期范围二进制矩阵秩测试二进制矩阵的秩是否偏离满秩特征离散傅里叶变换测试频谱中是否存在周期性或重复模式非重叠模板匹配测试特定非重叠模板出现频率是否异常重叠模板匹配测试特定重叠模板出现频率是否异常Maurer通用统计测试序列是否可被显著压缩即是否存在冗余线性复杂度测试序列的线性反馈移位寄存器复杂度是否正常串行测试长度为m的重叠串出现频率是否均匀近似熵测试相邻长度模式的频率差异是否合理累积和测试序列从头开始累积和的偏移是否异常随机游走测试在随机游走中访问特定状态次数是否异常随机游走变体测试上述游走中某状态总访问次数是否异常这15项覆盖了随机性最常见的失效模式偏差、周期性、局部相关性、可压缩性、低复杂度等等。所以它不只是一种测试而是一整套“体检套餐”。如果你只是想知道一个随机数发生器输出是不是均匀可能用不到这么重型的工具但如果你要做密码模块的合规验证或者需要写进测试报告那这套东西基本绕不开。1.2 版本现状与适用场景这里注意一下标题里说“最新”实际上NIST官方的STS工具目前仍然是sts-2.1.2这个版本。它发表于2010年左右配合的是SP 800-22 Rev.1a文档。听起来挺老但它在行业内的地位一点没动摇绝大多数测评机构和实验室用的就是它。第三方社区倒是维护了不少分支版本主要修复了在新版GCC编译器下的兼容性问题算法内核基本没变。所以如果你搜到的是sts-2.1.2不用怀疑是不是过时了它就是当前的主流版本。需要区分的是官网发布的源码包和某些社区补丁版功能上一致但编译难度不一样后面我会细说。这套工具适合谁用做密码算法、安全芯片、物联网设备随机数模块的工程师需要出随机性检测报告的质量测试人员做区块链抽签、游戏抽奖、蒙特卡洛模拟的开发者想验证自己的随机源质量高校里做信息安全方向研究的学生如果你只是写个简单应用用不着上全套15项但如果你要向客户或评审证明“我的随机源是可靠的”那NIST这套报告是目前最被认可的依据之一。2. 下载与部署前的准备工作2.1 从哪拿到官方源码包官方下载渠道是NIST的CSRC页面Computer Security Resource Center。入口路径大致是CSRC首页 - Projects - Random Bit Generation - Documentation and Software。这里能找到SP 800-22文档、测试套件的源码包还有配套的说明文件。下载到的压缩包名称一般是sts-2.1.2.zip之类。大小不大几百KB到几MB级别。源码包是纯C语言写的不依赖任何闭源库所以理论上在任何有C编译器的平台上都能编译。除了官网GitHub上也有不少镜像和修复版仓库搜“NIST Statistical Test Suite”就能找到。我的建议是如果系统比较新比如Ubuntu 22.04以上、macOS新版本优先用社区维护的补丁版编译省事很多如果你要严格追溯软件来源那就下官网原版然后自己手工处理编译问题。两种方式我都试过各有优劣后面会讲编译时的注意事项。下载完成后先做一件事校验文件完整性。官网一般会给校验值或者压缩包自身的MD5/SHA用sha256sum核对一下避免下载损坏或内容被篡改。这一步很多人跳过但做安全相关的东西习惯还是别丢。2.2 环境与依赖整理这套工具的依赖非常少。核心就两样C编译器gcc或clangmake工具如果你在某个较新的Linux发行版上编译可能还需要GNU GMP库libgmp-dev因为部分测试算法比如涉及大整数运算的地方会用到它。但这个不是每个版本都强依赖具体看编译时报错情况。我在Ubuntu、CentOS、macOS上都编译过。最省心的组合是Ubuntu gcc make基本开箱即用macOS需要装好Command Line ToolsXcode那套装上就行Windows则建议走WSL或者用MinGW/Cygwin但说实话不推荐在Windows原生环境折腾后面我会单独说。装好依赖之后验证一下环境gcc --version make --version如果有libgmp需要确认dpkg -l | grep libgmp-dev # Debian/Ubuntu系 rpm -qa | grep gmp-devel # CentOS/RHEL系没有的话Ubuntu下直接sudo apt install gcc make libgmp-devCentOS系用yum install gcc make gmp-devel。这些基础依赖装好后面编译基本不会卡住。3. 安装编译把源码变成可执行文件3.1 Linux/macOS下的编译步骤拿到源码包后解压、进入目录、编译标准三连unzip sts-2.1.2.zip cd sts-2.1.2 cd sts make注意这里有个很坑的目录层级。解压后源码里的可执行工程目录不是顶层而是在sts-2.1.2/sts这个子目录。如果你直接在顶层执行make大概率会提示找不到makefile别慌cd进去就行。make成功之后会在当前目录生成一个名为assess的可执行文件。你可以立刻跑一下试试./assess 1000000如果前面编译顺利这里会进入交互界面列出各种测试选项。先不用管怎么填能正常出现菜单说明程序已经编译成功。不过如果你用的系统比较新比如Ubuntu 22.04之后的发行版或者较新的GCC 12官网原版源码直接make大概率会报错。我遇到的典型报错有这么几类某个源文件里用了旧的函数声明方式新GCC直接报conflicting types链接时找不到数学库函数比如undefined reference to powgmp.h头文件找不到报fatal error: gmp.h: No such file or directory遇到这些情况常见的处理手段第一把makefile里链接的地方加上-lm确保数学库被正确链接。很多老C程序都需要这个。第二如果报类型冲突去对应源文件里改函数声明把它改成标准C原型。具体哪个文件、哪个函数报错信息里会写得清清楚楚。第三装好libgmp-dev再重新make。如果你不想在这些兼容性问题上浪费时间直接找社区补丁版很多仓库已经把这些坑都填好了下载后make一把过。我的经验是日常自己做测试、跑数据用社区补丁版更省心如果是给客户出报告、涉及审计溯源那还是用官网原版并记录好编译环境信息。3.2 Windows下怎么办Windows下编译这套工具老实说体验不是很好。原版makefile是按Unix环境写的直接在Windows裸环境里做需要改很多东西。我试过几种方案最省事的是WSLWindows Subsystem for Linux。在WSL里装一个Ubuntu然后按Linux那套流程走编译、运行、读报告都正常。这是我最推荐的方式尤其是你只是想在Windows电脑上跑测试没必要跟makefile死磕。其次是Cygwin或MinGW。Cygwin环境下编译一般也能过但运行时偶尔会有路径和动态库的问题。MinGW的话需要自己手动创建工程或者修改makefile工作量不小。第三种是用Visual Studio新建一个工程把源码文件全部拖进去编译。这条路理论上可行但源文件里有一些POSIX相关的调用要在VS里做兼容处理过程比较痛苦。非必要不建议。所以我的结论就是不管你的正式工作环境是Windows还是macOS跑这个工具都建议放到Linux环境或WSL里。它本身是个命令行工具没有图形界面在Linux里跑最顺报告生成、脚本化批量测试也方便。4. 准备测试数据与运行测试4.1 数据文件格式第一大坑这个坑我估计90%的人第一次跑都踩过NIST这个工具读入的数据文件不是二进制文件而是纯文本文件里面只包含ASCII字符“0”和“1”每个bit对应一个字符。也就是说如果你把一个二进制文件比如/dev/urandom直接读出来的字节丢给assess程序会按字符去读读出来的东西全是乱码统计结果毫无意义。这个细节在官方文档里有写但很多教程没重点强调。我刚开始用的时候也犯过糊涂总觉得“随机数嘛二进制文件应该更自然”结果跑出来的结果惨不忍睹P-value各种0排查了半天才发现是数据格式的问题。正确的数据是这样的一串字符01101001011000010111001001100101011011100110010001101111...文件里最好不要有空格、换行等其他字符。文本末尾有一个换行符一般影响不大因为程序是按指定长度读取的但中间一旦混入换行就会被当成额外的bit导致统计错位。另外测试时你告诉程序每条序列长度为n序列数量为m那么程序一共需要读取n*m个字符。文件不够长时程序要么报错要么后面的序列会重复使用数据不管哪种情况都会影响结果。所以准备数据时一定要保证文件足够大。4.2 生成测试数据实用脚本如果你要测的是一个已有的随机数生成器输出可以通过编程接口把生成的随机数转成0/1文本流。如果只是想快速先跑通流程可以用系统熵源生成测试文件我一般这么干import os total_bits 100 * 1000000 # 100条序列每条100万bit byte_count total_bits // 8 with open(/dev/urandom, rb) as f: raw f.read(byte_count) bits .join(format(b, 08b) for b in raw) with open(data/random_bits.txt, w) as out: out.write(bits)这段脚本读/dev/urandom把每个字节转成8个0/1字符写到一个文本文件里。注意生成的文件体积会比较大100万bit就是100万字符约1MB如果你要跑100条序列就是1亿个字符大概100MB。磁盘空间和内存都要预留好。如果你要测的是某个伪随机数生成器PRNG也很简单把PRNG的输出字节用同样的方式转成0/1文本即可。关键点只有一个——生成完数据后先随机抽查一下文件内容确认里面只包含0和1没有别的字符。4.3 交互式运行界面选项与操作流程编译成功、数据文件准备好了就可以正式跑测试了。最基础的方式是交互式运行cd sts-2.1.2/sts ./assess 1000000这个命令行参数1000000就是每条测试序列的长度nbit数也是最常用的取值之一。程序启动后会进入交互菜单。第一次用的人可能会被一堆提示唬住其实核心就几步第一步选择输入方式。程序会列出数据来源选项包括Input File和内置的伪随机数生成器。我们当然选Input File也就是输入外部数据文件一般对应序号0。然后在提示后面输入你的数据文件路径比如data/random_bits.txt。第二步选择测试项。菜单会列出从Frequency Test到Random Excursions Variant Test等所有选项让你选择是跑全部测试还是只跑其中几项。一般输入0代表全部测试不同版本菜单含义略有差异看提示文字判断即可。如果只想跑某几项就按提示输入对应的测试编号。第三步设置参数。如果选了全部测试程序会遍历15项测试每一项都可能询问参数。例如块内频率测试要指定块长M默认128非重叠模板匹配要指定模板长度m默认9近似熵测试要指定块长m默认10串行测试要指定块长m默认16线性复杂度测试要指定块长M默认500大部分情况直接回车取默认值就可以。只有当你测的数据特性需要特殊参数时才需要去调整。这里有个原则参数设置会影响测试的灵敏度和适用范围公开的测试报告一般都会注明使用的参数所以最好把参数记录下来。第四步输入要测试的序列数量m。如果你数据文件足够大建议至少设100。比如每条100万bit共100条总计1亿bit这是行业内比较常见的一个配置。全部输入完成后程序开始逐项跑测试。界面上会滚动输出进度跑完显示“Statistical Testing Complete”。耗时取决于数据量和机器性能数据量大时可能要跑几十分钟甚至更久耐心等就好。4.4 用管道实现自动化批处理交互式跑测试虽然直观但有个问题是“不能出错”输错一个序号就得从头再来。而且如果12个参数都要手填重复性很高。我更推荐写一个自动应答脚本把输入按顺序预置好用管道喂给assess。以bash为例思路是这样的cd sts-2.1.2/sts { echo 0 # 选择输入文件方式 echo data/random_bits.txt # 数据文件路径 echo 0 # 选择全部测试 echo # 块内频率测试参数回车取默认 echo # 非重叠模板测试参数 # ... 更多参数按程序提示顺序补齐 echo 100 # 序列数量m } | ./assess 1000000这段脚本有一个前提你必须搞清楚你所用版本的交互菜单顺序每个echo对应哪一步。不同版本和不同编译分支的菜单顺序可能不一样第一次写的时候建议先手动跑一遍把提示顺序记下来再写成脚本。更稳妥的自动化方案是用Python的pexpect或paramiko这类交互库可以按输出内容动态应答比死板的管道更可靠。但老实说对大多数场景管道脚本已经够用了。我自己最常用的做法是把脚本里所有参数放到一个配置文件里换数据文件、换参数时只改配置不用改脚本逻辑。跑完之后程序会把结果写入experiments目录这是读取结果的关键路径。5. 测试结果解读不只数P-value5.1 结果文件在哪看跑完测试后进入sts目录下的experiments文件夹里面有按日期生成的结果目录。核心文件是两个finalAnalysisReport.txt汇总报告包含每项测试的判断结论results.txt详细结果包含每条序列每项测试的P-value等原始数据另外目录里可能还有data/和stats/两个子目录里面存放了中间数据和统计细节。日常看finalAnalysisReport.txt就够了如果需要做深入分析再去翻results.txt。打开finalAnalysisReport.txt你会看到每个测试项下面都有很多行包括测试名称、序列数、P-value、比例Prop和结论Success/Failure。这个文件就是你要写进报告里的核心依据。5.2 P-value、通过率与判定标准结果解读的核心指标是P-value。它的含义大致是在原假设“数据是随机的”成立的前提下观测到当前或更极端统计量的概率。P-value越小说明数据越不像随机的。在实际判定时常用显著性水平α0.01。也就是说单项测试的P-value ≥ 0.01判定通过SuccessP-value 0.01判定失败Failure注意这是“单个序列”的判定。而实际测试时通常测了m条序列所以还要看通过率。通过率即m条序列中P-value≥0.01的比例。这个比例不是100%才算合格而是要落在可接受区间内。区间下限计算公式是[ \hat{p} 1 - \alpha - 3\sqrt{\frac{\alpha(1-\alpha)}{m}} ]以m100、α0.01为例[ 1 - 0.01 - 3\sqrt{\frac{0.01 \times 0.99}{100}} 0.99 - 3 \times 0.00995 \approx 0.96015 ]也就是说100条序列中至少要有97条通过该项测试才算合格。如果某测试100条里只有95条通过虽然看起来“大部分都行”但从统计判定上看已经出问题需要深究。另外finalAnalysisReport里还会把P-value的分布均匀性做一个统计把所有P-value按10个区间划分看看分布是否均匀。这个均匀性本身也是一个判断指标一般看报告里的“P-value of P-values”或类似字段太小也说明分布异常。这里必须强调一点一次测试全部通过只能说明“没发现明显不随机的证据”不能推导出“这个生成器绝对安全”。尤其对于密码学用途随机数测试只是必要条件不是充分条件。做安全评估时还要结合熵源分析、理论设计、物理特性等综合判断。5.3 常用测试参数选择建议测试参数不是随便拍脑袋定的不同的参数组合适合不同的应用场景。我总结一下常用配置参数推荐值说明序列长度n1000000 bit行业最常见兼容所有测试项序列数量m100~1000越多统计越可靠但耗时越长块内频率块长M128或10000128是默认10000适合测长块偏差非重叠模板长度9或10默认9测试模板匹配频率串行测试块长16默认值线性复杂度块长500 或 1000默认500序列长度n是关键。如果n太小有些测试项会因为样本量不足而无法计算或结果不稳定n太大文件体积和耗时都会显著增加。100万bit是一个比较好的平衡点。序列数量m方面最少也别低于20否则统计判定的置信度很低。我自己的习惯是先跑100条快速筛查如果发现问题再加到1000条做二次确认。数据量越大越不容易被偶然性干扰。6. 常见问题与排查技巧实录6.1 编译阶段的经典报错这个工具最让人头疼的就是在“新系统编译老代码”时会遇到一堆问题。我把实际遇到过的报错整理成速查表报错信息原因解决办法fatal error: gmp.h: No such file or directory缺少GMP库安装libgmp-dev或gmp-develundefined reference topow数学库未链接makefile里加-lmconflicting types for ...老式函数声明与新GCC冲突修改对应源文件中的函数声明cannot find -lxxx缺少某个链接库安装对应开发包*** Error 1编译中断看完整输出定位具体源文件如果不想自己修这些直接找社区补丁版编译这没什么不好意思的。工具只是手段把时间花在测试分析和产品改进上比在编译器兼容性上死磕更有价值。6.2 运行阶段容易踩的坑编译过了后面还有几个高频问题第一数据文件路径写错。程序问输入文件名时它是在sts目录下找的所以如果你把数据文件放在sts/data/下路径就写data/xxx.txt。如果你放在别的目录用相对路径或绝对路径都行但确保当前工作目录和路径一致。我建议干脆把数据文件放到sts/data/下最不容易出错。第二文件里混入非0/1字符。有时用脚本生成数据脚本里print(bits)自动加了换行导致每个bit后面都有一个换行符。这样程序读到第n个字符时可能一半是换行一半是bit结果全乱套。生成数据后务必检查文件大小是否符合预期并抽查文件内容。第三内存和运行时间预估不足。全测100条100万bit的序列是个不小的工程。我试过在普通笔记本上跑全部15项测试可能耗时几十分钟到数小时。跑之前先看看磁盘剩余空间和内存别跑一半系统卡死。更务实的方式是先跑20条快速验证流程确认无误后再跑完整数据。第四有些测试项报Inf或NaN。这通常是因为参数设置不合理或数据量不足。比如线性复杂度测试要求每条序列长度是块长M的整数倍如果不满足计算结果就会出现异常。遇到这种情况优先检查n和M的整除关系。6.3 对随机性测试的几个提醒最后说几点我对这套工具的总体看法。第一NIST STS不是万能的。它虽然有15项测试但也只是一组统计筛子。某些类型的随机数缺陷它未必能测出来。比如一些结构上很复杂但可预测的随机序列可能能通过部分统计测试。所以不要因为“NIST测试全过”就高枕无忧必要时用TestU01、Dieharder等其他测试套件交叉验证。第二测试结论一定要结合上下文。同样是测一个PRNG在加密场景和非加密场景对随机性要求完全不同。NIST测试通过率差一点在抽奖系统里可能无伤大雅但在密钥生成场景里就是致命问题。判定标准要在测试前就定好别等结果出来了再“灵活解释”。第三测试过程要保持可复现。记录数据来源、生成方式、测试参数、软件版本、编译环境这样才能在出问题时追踪或者让第三方复核。我见过不少团队测试跑完了结果文件还在但没人记得当时用的什么参数报告基本废了。第四关注“失败”的测试项但也不要过度反应。哪怕一个高质量的随机源在多序列测试中某几项出现失败也可能是正常波动。这时要看失败比例是否超过统计允许范围而不是一看到Failure就否定整个生成器。反过来如果某项测试失败得非常彻底比如P-value全是0那就别心存侥幸了一定是哪里出了问题先检查数据生成和预处理流程。拿我自己这次的经历来说最开始跑数据因为数据文件里带了换行符导致频率测试和游程测试全军覆没。当时我还以为是熵源模块有问题折腾了半天最后才发现是脚本里print默认换行惹的祸。把数据重新生成、清理干净之后所有测试项很快就通过了。这种“假阳性”的坑新手特别容易踩。如果你以后也遇到NIST测试大面积失败我的建议是先别怀疑你的随机数发生器第一步检查数据文件格式第二步检查参数设置第三步再回去审视数据源。工具用熟了之后你会慢慢形成一套自己的排查节奏测试效率也会高很多。
RELATED

相关推荐

PHP手机商城源码部署实战:从环境搭建到二次开发与避坑指南

PHP手机商城源码部署实战:从环境搭建到二次开发与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/7 1:17:00
STM32F103 DMA+空闲中断实现USART不定长收发实战

STM32F103 DMA+空闲中断实现USART不定长收发实战

1. 项目缘起与整体方案设计STM32F103 这颗芯片在嵌入式圈子里算是老面孔了,C8T6 最小系统板几块钱就能买到,资料铺天盖地,但真正把 USART 收发做到“稳、快、不丢包”的人其实没想象中多。我见过太多项目里串口就是HAL_UART_Receive轮询&…

📅 2026/10/7 1:17:00
Linux thermal framework 通用架构详解:从传感器到冷却设备的功耗管理闭环

Linux thermal framework 通用架构详解:从传感器到冷却设备的功耗管理闭环

1. 从一次温控翻车说起:thermal framework 到底管什么前阵子帮朋友排查一块嵌入式板子,现象很典型:设备跑高负载任务不到三分钟,CPU 频率就被死死压在低位,性能直接腰斩,但外壳摸上去并不烫。第一反应是散热…

📅 2026/10/7 1:17:00
MORE NEWS

更多资讯

📰

Hyperf 配置组件(hyperf/config)完全指南:配置文件结构、Config 对象、`[Value]` 注解与环境变量实战

后端微服务 【免费下载链接】hyperf 🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease. 项目地址: https://gitcode.com/gh_mirrors/hy/hyperf 点击查看 免费下载 本篇技术指南以…

📰

力扣双周赛 172 全题解:从二维 0-1 背包到 O(1) 位运算(基于 codeforces-go 算法模板库)

科学计算 【免费下载链接】codeforces-go 算法竞赛模板库 by 灵茶山艾府 💭💡🎈 项目地址: https://gitcode.com/GitHub_Trending/co/codeforces-go 点击查看 免费下载 本篇技术指南以 leetcode/biweekly/172/README.md 为核心&a…

📰

Goa 仓库开发指南全解析:AGENTS.md 编码规范、代码生成契约与问题复现协议

后端代码生成API设计微服务 【免费下载链接】goa Design-first Go framework that generates API code, documentation, and clients. Define once in an elegant DSL, deploy as HTTP and gRPC services with zero drift between code and docs. 项目地址: https:/…

📰

XMall 分布式电商项目中的 Dubbo 架构实践:服务注册、消费与负载均衡全解析

电商后端微服务 【免费下载链接】xmall 基于SOA架构的分布式电商购物商城 前后端分离 前台商城:Vue全家桶 后台管理系统:Dubbo/SSM/Elasticsearch/Redis/MySQL/ActiveMQ/Shiro/Zookeeper等 项目地址: https://gitcode.com/gh_mirrors/xm/xmall 点击查看 免费下载 本…

📰

openpilot 开源驾驶辅助实战指南:车道居中和自适应巡航,三步装好上手

openpilot 开源驾驶辅助实战指南:车道居中和自适应巡航,三步装好上手 【免费下载链接】openpilot openpilot is an operating system for robotics. Currently, it upgrades the driver assistance system on 300 supported cars. 项目地址: https://g…

📰

如何用 Win11Debloat 移除 Windows 11 预装应用和关闭遥测(附完整回滚步骤)

如何用 Win11Debloat 移除 Windows 11 预装应用和关闭遥测(附完整回滚步骤) 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various ot…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬