【密码学】一文读懂MT19937

简介: 瞄了一眼redis的源码,然后发现里面好玩的东西还挺多的,本文来聊一聊redis当中用到的一个随机数生成算法 mt19937,具体源码参见文末的参考资料,在这里就不贴到文本当中了。对于redis源码里面用的是mt19937-64本文先来看一下32位的版本,对于64位的版本,只不过状态当中元素用的是64位的元素,整个运算过程框架是类似的。「梅森旋转算法」(「Mersenne twister」)是一个伪随机数生成算法,由松本真和西村拓士在1997年提出来的,可以快速产生高质量的伪随机数,修正了古典随机数生成算法当中的很多缺陷。19937这个名字来源于周期长度为梅森素数 。

【密码学】一文读懂MT19937


]MO$QND[_P_8_@G]TCR8GZI.jpg

瞄了一眼redis的源码,然后发现里面好玩的东西还挺多的,本文来聊一聊redis当中用到的一个随机数生成算法 mt19937,具体源码参见文末的参考资料,在这里就不贴到文本当中了。对于redis源码里面用的是mt19937-64本文先来看一下32位的版本,对于64位的版本,只不过状态当中元素用的是64位的元素,整个运算过程框架是类似的。

「梅森旋转算法」「Mersenne twister」)是一个伪随机数生成算法,由松本真和西村拓士在1997年提出来的,可以快速产生高质量的伪随机数,修正了古典随机数生成算法当中的很多缺陷。19937这个名字来源于周期长度为梅森素数 。


生成器结构

OBAK1U[T7G]C@CA0)UAVAKD.pngMT19937生成器结构

如上图所示,mt19937的随机数生成器结构首先需要一个uint32的种子,然后生成一个具有624个uint32数组的状态数组。生成状态数组之后,进行一次旋转,最终可以输出624个随机的uint32。然后重复执行旋转操作,就可以得到一个周期为 的随机数生成器了。

对于mt19937整个计算过程来说,虽然比我之前提到过的线性同余法复杂不少,但是整个流程还是比较清晰的,对于里面的原理,我其实也了解的不是很多,因此在这里就不展开讲了,如果想了解原理的读者,可以参考文末的参考资料当中的论文进行学习,本文是指来聊一下这个东西具体是怎么计算的。到这里,这篇文章我就水完了,逃~~~


代码实现

老样子了,还是给出我写的两个语言的参考,注意本文讲的是32位的mt19937,再去看redis源码当中的实现的时候用的是mt19937-64。

Go

const (
  n = 624
  m = 397
)
type MT19937 struct {
  state []uint32
  index int
}
func New(seed uint32) *MT19937 {
  mt := &MT19937{
    state: make([]uint32, n),
    index: 0,
  }
  mt.state[0] = seed
  for i := uint32(1); i < n; i++ {
    mt.state[i] = 1812433253*(mt.state[i-1]^mt.state[i-1]>>30) + i
  }
  return mt
}
func (mt *MT19937) twist() {
  for i := uint32(0); i < n; i++ {
    y := (mt.state[i] & 0x80000000) + (mt.state[(i+1)%n] & 0x7fffffff)
    mt.state[i] = (y >> 1) ^ mt.state[(i+m)%n]
    if y%2 != 0 {
      mt.state[i] = mt.state[i] ^ 0x9908b0df
    }
  }
}
func (mt *MT19937) Uint32() uint32 {
  if mt.index == 0 {
    mt.twist()
  }
  y := mt.state[mt.index]
  y = y ^ y>>11
  y = y ^ y<<7&2636928640
  y = y ^ y<<15&4022730752
  y = y ^ y>>18
  mt.index = (mt.index + 1) % n
  return y
}

Rust

const N: usize = 624;
struct MT19937 {
    state: [u32; N],
    index: usize,
}
impl MT19937 {
    pub fn new(seed: u32) -> Self {
        let mut mt = MT19937 {
            state: [0; N],
            index: 0,
        };
        mt.state[0] = seed;
        for i in 1..N {
            mt.state[i] = 1812433253 * (mt.state[i - 1] ^ (mt.state[i - 1] >> 30)) + i as u32;
        }
        mt
    }
    fn twist(&mut self) {
        for i in 0..N {
            let x = (self.state[i] & 0x80000000) | (self.state[(i + 1) % N] & 0x7fffffff);
            let mut x_a = x >> 1;
            if x % 2 != 0 {
                x_a ^= 0x9908b0df;
            }
            self.state[i] = self.state[(i + 397) % N] ^ x_a;
        }
        self.index = 0;
    }
    fn rand(&mut self) -> u32 {
        if self.index >= N {
            self.twist();
        }
        let y = self.state[self.index];
        self.index += 1;
        y ^ y >> 11
    }
}


相关文章
|
Web App开发 Rust 算法
【密码学】一文读懂ChaCha20
好久没写新的加密算法的原理了, 这次所选取的加密算法结构比较简单, 一起来看一下吧。
10560 154
【密码学】一文读懂ChaCha20
|
存储 运维 NoSQL
Redis7.0 核心特性简介
Redis自 2009 年诞生以来,已经走过了 13 年。在这漫长的 13 年中,Redis 从小小的开源项目逐步演变成为当今最受欢迎的内存数据库之一,被用于多种场景,帮助解决很多问题
4294 0
Redis7.0 核心特性简介
|
Python
一条龙操作有效解决PermissionError: [WinError 5] 拒绝访问的问题
一条龙操作有效解决PermissionError: [WinError 5] 拒绝访问的问题
2491 0
|
存储 算法 安全
【密码学】非对称加密算法 - ECDH
由于 ECC 密钥具有很短的长度,所以运算速度比较快。到目前为止,对于 ECC 进行逆操作还是很难的,数学上证明不可破解,ECC 算法的优势就是性能和安全性高。实际应用可以结合其他的公开密钥算法形成更快、更安全的公开密钥算法,比如结合 DH 密钥形成 ECDH 密钥协商算法,结合数字签名 DSA 算法组成 ECDSA 数字签名算法。ECDH算法常常用来进行密钥的协商,协商好密钥后,用来解决上面的密钥分配问题,将对称加密的密钥安全的传到对端设备。算法加密/解密数字签名密钥交换RSA✅✅✅❌。
5724 0
|
算法 安全 量子技术
【Python】蒙特卡洛模拟 | PRNG 伪随机数发生器 | 马特赛特旋转算法 | LCG 线性同余算法 | Python Random 模块
【Python】蒙特卡洛模拟 | PRNG 伪随机数发生器 | 马特赛特旋转算法 | LCG 线性同余算法 | Python Random 模块
1206 0
|
8月前
|
SQL JSON 监控
JSON 日志分析的“正确姿势”:阿里云 SLS 高效实践指南
JSON 日志因灵活易扩展而广泛应用,但其海量数据也带来分析挑战。本文系统介绍阿里云日志服务(SLS)中处理 JSON 日志的最佳实践,涵盖数据预处理、索引配置、JSON 函数使用及 SQL 智能生成,助你高效挖掘日志价值。
3095 23
|
关系型数据库 MySQL
【MySQL】经典练习题(部门表、员工表、工资表)
【MySQL】经典练习题(部门表、员工表、工资表)
778 0
|
Web App开发 IDE 测试技术
使用Selenium进行自动化测试:从入门到实践
【6月更文挑战第1天】本文介绍了使用Selenium进行自动化测试的基础知识,包括Selenium工具集的三大组件:WebDriver、IDE和Grid。Selenium支持多种浏览器和编程语言接口。文中详细阐述了安装配置过程,如安装浏览器驱动和Selenium库,并提供了一个Python示例,演示如何初始化WebDriver、打开网页、操作元素及关闭浏览器。此外,文章指出Selenium可扩展实现更复杂测试,可与其他测试框架结合以提升测试效率。
|
算法 安全 程序员
【C++ 随机数生成器】深入解析C++ 随机数生成器mersenne_twister_engine等
【C++ 随机数生成器】深入解析C++ 随机数生成器mersenne_twister_engine等
940 0
|
JSON 小程序 JavaScript
面试官说,布局小程序页面记得用TDesign组件库
面试官说,布局小程序页面记得用TDesign组件库