对JavaScript中的Math.random随机函数破解

news2025/7/27 12:29:33

什么是随机

在这里插入图片描述

在通常的说法中,随机性是指事件中明显实际缺乏可预测性,事件、符号或步骤的随机序列通常没有顺序

举个例子,比如我们在抛硬币,硬币的结果取决于很多因素,比如说我们施加的力,空气阻力,引力等,但是如果我们知道影响硬币的所有因素,并且知道这些因素准确的值,我们就能预测硬币落下时,是正面还是反面

伪随机

假如我们有一个算法,我们给他设置一个初始值,然后用这个算法生成下一个数字,然后再用生成的这个数字继续生成下一个……

12 --------> 30 --------> 57 --------> 33

这个初始值被称之为seed(种子),过段时间后我们可以得到一组相同的数字,这个过程叫做周期,周期越大,说明我们的算法越好,这种随机数生成的算法被称之为伪随机,它不是真正的随机生成

伪随机生成器通常用于游戏中,比如角色一开始生成的地方,但是不会用于密码学中,因为在一定条件下,伪随机生成器是可以被破解的

Math.random

在JavaScript中,有一个叫Math.random随机生成的函数,他是一个原生的函数,几乎所有的JavaScript框架都包含这个函数

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

在这里插入图片描述

Math.random函数会返回一个大于0且小于1的浮点伪随机数,chrome浏览器也用的是JavaScript,并且包含了这个函数,他们使用的算法是v8

而v8是开源的,并且是由google进行维护的

ht#tps://github.com/v8/v8/tree/7a4a6cc6a85650ee91344d0dbd2c53a8fa8dce04
htt#ps://v8.dev/blog/math-random

在这里插入图片描述

在这里插入图片描述

可以发现有一个xorshift128+的算法,现在我们去看看math.random函数的源代码

在这里插入图片描述

static inline void XorShift128(uint64_t* state0, uint64_t* state1) {
    uint64_t s1 = *state0;
    uint64_t s0 = *state1;
    *state0 = s0;
    s1 ^= s1 << 23;
    s1 ^= s1 >> 17;
    s1 ^= s0;
    s1 ^= s0 >> 26;
    *state1 = s1;
  }

看起来并不复杂,只是一些异或操作和移位的操作,这个函数将state0和state1变成s0和s1,然后s1进行了异或和移位

我们不用对整个算法进行理解然后再去破解它,因为我们可以用z3这个smt求解器

z3

在这里插入图片描述

z3是由微软公司开发的smt求解器,我们可以将问题作为方程式列出,然后指定约束,z3就可以自动的解决这个问题

比如下面这个方程式

x + 2y = 7

我们可以使用z3来帮助我们计算x和y的值

from z3 import *

x = Int('x')
y = Int('y')
solve(x + 2*y == 7) 

在这里插入图片描述

我们还可以用z3进行逻辑推理,弱哈希破解,数独……

对Math.random函数破解

在这里插入图片描述

首先,我们用z3创建64位的占位符值,因为xorshift128有两个状态,所以我们将这两个状态设置为占位符变量

solver = z3.Solver()
se_state0, se_state1 = z3.BitVecs("se_state0 se_state1", 64)

然后我们还需要从v8生成的随机值进行运算,我们按下f12,进入控制台,输入以下代码,随机生成五个数

Array.from(Array(5), Math.random)

在这里插入图片描述

把这五个数放到我们的脚本里,遍历这五个随机数

sequence = [0.6199046082820001, 0.6623637813965961, 0.7190181683749095, 0.06169296721449724, 0.915799780594273]
sequence = sequence[::-1]

然后我们将v8 xorshift128算法的源代码复制过来,做一些改动

在这里插入图片描述

for i in range(len(sequence)):
    se_s1 = se_state0   #用占位符值替换状态
    se_s0 = se_state1   #用占位符值替换状态
    se_state0 = se_s0   
    se_s1 ^= se_s1 << 23
    se_s1 ^= z3.LShR(se_s1, 17)  #设置逻辑移位而不是算数移位
    se_s1 ^= se_s0
    se_s1 ^= z3.LShR(se_s0, 26)
    se_state1 = se_s1

然后还需要写一些代码来进行运算

	float_64 = struct.pack("d", sequence[i] + 1) #然后获取 se_state0的值并用struct模块把它变成双精度的值
    u_long_long_64 = struct.unpack("<Q", float_64)[0] #将其解压位64位无符号的整数
    mantissa = u_long_long_64 & ((1 << 52) - 1) #得到尾数的低52位再减去1
    solver.add(int(mantissa) == z3.LShR(se_state0, 12)) #添加约束来比较尾数

在v8里,还有一个函数叫做todouble,它的作用是转换,我们将这个源代码也放入我们的脚本

在这里插入图片描述

	state0 = states["se_state0"].as_long()
    u_long_long_64 = (state0 >> 12) | 0x3FF0000000000000
    float_64 = struct.pack("<Q", u_long_long_64)
    next_sequence = struct.unpack("d", float_64)[0]
    next_sequence -= 1

现在我们就有一个可以破解Math.random函数的脚本了

脚本完全代码

#!/usr/bin/python3
import z3,struct,sys

sequence = [0.6199046082820001, 0.6623637813965961, 0.7190181683749095, 0.06169296721449724, 0.915799780594273]

sequence = sequence[::-1]
solver = z3.Solver()
se_state0, se_state1 = z3.BitVecs("se_state0 se_state1", 64)

for i in range(len(sequence)):
    se_s1 = se_state0
    se_s0 = se_state1
    se_state0 = se_s0
    se_s1 ^= se_s1 << 23
    se_s1 ^= z3.LShR(se_s1, 17)
    se_s1 ^= se_s0
    se_s1 ^= z3.LShR(se_s0, 26)
    se_state1 = se_s1

    float_64 = struct.pack("d", sequence[i] + 1)
    u_long_long_64 = struct.unpack("<Q", float_64)[0]
    mantissa = u_long_long_64 & ((1 << 52) - 1)
    solver.add(int(mantissa) == z3.LShR(se_state0, 12))

if solver.check() == z3.sat:
    model = solver.model()

    states = {}
    for state in model.decls():
        states[state.__str__()] = model[state]

    state0 = states["se_state0"].as_long()
    u_long_long_64 = (state0 >> 12) | 0x3FF0000000000000
    float_64 = struct.pack("<Q", u_long_long_64)
    next_sequence = struct.unpack("d", float_64)[0]
    next_sequence -= 1

    print(next_sequence)

运行这个脚本,获得下一个随机数

在这里插入图片描述

在这里插入图片描述

成功正确预测了下一个随机数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/16703.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linus shell 在一个脚本中调用另外一个脚本变量

1.新建public.sh文件&#xff0c;并添加以下内容&#xff1a; 2.新建ceshi.sh文件&#xff0c;并添加以下内容&#xff1a; 3.在终端赋予ceshi.sh文件执行权限&#xff0c;并运行该文件。

角度回归(复数与欧拉公式,L1,L2)

文章目录1 BEV下&#xff0c;Eula 损失函数2 BEV下&#xff0c;PointPillars使用sin联合SmoothL13 透视图下&#xff0c; MultiBin 全局方向损失4 L1/L2-norm 的周期损失函数1 BEV下&#xff0c;Eula 损失函数 Yolo-complex的论文中&#xff0c;对于BEV视角下&#xff0c;目标…

SDN和NFV的区别?

前言 网络功能虚拟化&#xff08;Network Functions Virtualization&#xff0c;NFV&#xff09;是一种关于网络架构的概念。我们平时使用的x86服务器由硬件厂商生产&#xff0c;在安装了不同的操作系统以及软件后实现了各种各样的功能。而传统的网络设备并没有采用这种模式&am…

2000-2019年各省产业结构合理化指数(干春晖泰尔指数)

2000-2019年省级产业结构合理化指数&#xff08;干春晖泰尔指数&#xff09; 1、来源&#xff1a;统计NJ及各省统计NJ 2、时间2000-2019年 3、数据说明&#xff1a;含原始数据和计算过程 4、范围包括全国31省 5、指标包括&#xff1a;各省总产值、第一产业增加值、第二产业…

C++基础知识要点--表达式 (Primer C++ 第五版 · 阅读笔记)

目录表达式基础算术运算符逻辑和关系运算符赋值运算符递增和递减运算符成员访问运算符条件运算符位运算符sizeof运算符逗号运算符类运算符运算符优先级表表达式 基础 当一个对象被用作右值的时候&#xff0c;用的是对象的 值&#xff08;内容);当对象被用作左值的时候&#x…

Linux 信号

概念&#xff1a;信号不是信号量&#xff0c;信号量是进程间的一种通信方式&#xff0c;信号是系统中的软件中断&#xff0c;指一种事件通知机制&#xff0c;通知进程发生了某个事件&#xff0c;打断当前的操作&#xff0c;去处理这个事件。 种类&#xff1a;一共有62种信号&a…

Linux之用户管理、权限管理、程序安装卸载

一. 用户管理 1. 查看账户 (1). 查看当前账号&#xff1a;whoami ​​(2). 查看系统当前登录的账号&#xff1a;who ​​补充常用选项&#xff1a; ​​(3). 查看系统所有的账号&#xff1a; cat /etc/passwd ​​2. exit&#xff1a;退出登录账户 如果是图形界面&#xff0c…

curl命令的常用操作

curl是非常实用的命令行工具&#xff0c;用来与服务器之间传输数据。它的命令行参数多达几十种。 在Linux环境中使用curl命令可以进行接口测试。利用curl对http协议发送Get/Post/Delete/Put请求,同时还可以携带header来满足接口的特定需求。 curl命令的语法 curl[options] [U…

Linux03-网络设置

一、说明 在上一节&#xff0c;咱使用VMware安装了虚拟机&#xff0c;网络设置选择了 “桥接模式” &#xff0c;本节咱们来具体讨论一下网络连接方式和网络设置。 实验环境&#xff1a;CentOS7 VMware 二、桥接模式 当我们设置桥接模式时&#xff0c;虚拟机是直接使用物理…

eNSP出现错误,错误代码40暴力解决方案

如果你和我一样&#xff0c;在eNSP中启动一个设备时发生了错误&#xff0c;错误代码为40&#xff0c;那么这篇文件可能会帮助你。 首先你可以仔细地按照这篇说明中的做法进行操作&#xff0c;如果你电脑也是win10&#xff0c;并且之前没有安装过wireshark&#xff0c;virtualb…

后端总说他啥也没动,我从线上调了一下测试接口,你再说一句动没动

◇ 不知道广大前端同学有没有过这样的经历&#xff0c;在做新需求联调的时候&#xff0c;原本上一个版本已经做的好好的功能&#xff0c;前后端已经联调好的。这次做需求的时候&#xff0c;测试发现好多地方都不对了。 ◇ 开发人员经常说的一句话就是&#xff1a;我啥也没动啊…

Java -- 每日一问:你了解Java应用开发中的注入攻击吗?

典型回答 注入式&#xff08;Inject&#xff09;攻击是一类非常常见的攻击方式&#xff0c;其基本特征是程序允许攻击者将不可信的动态内容注入到程序中&#xff0c;并将其执行&#xff0c;这就可能完全改变最初预计的执行过程&#xff0c;产生恶意效果。 下面是几种主要的注…

Web前端:2022年Web开发者的五大CSS工具

据相关数据统计&#xff0c;2018年至2028年&#xff0c;网络开发人员的就业预计将增长13%&#xff0c;这意味着网站开发者的需求量很大&#xff0c;而企业需要专业人员来构建网站&#xff0c;而高效制作优秀网站的最佳方法是拥有最好的web开发工具。 对优秀web开发工具的需求使…

设信号x(t)=cos(2π×50t)+2×cos(2π×400t),试将它的两个频率分量分离,并绘制它们的时域波形及频谱图

以下程序无需赋值&#xff0c;直接运行即可&#xff1a; &#xff08;已验证可以运行&#xff09; function [yl,yh]shiyan49 fs1600; %采样频率 Tt0.02; %信号周期 T04*Tt; %记录长度 [xn,wk,N]shiyan40(fs,T0); Mlength(wk); if M2 rp1;rs80; f1wk(1)*fs/N; f2wk(2…

升余弦滤波器的FPGA实现

目录 升余弦滤波器与无码间串扰&#xff08;一&#xff09; 升余弦滤波器与无码间串扰&#xff08;二&#xff09; 升余弦滤波器的FPGA实现 一、FIR ip核 成形滤波器采用vivado中的FIR ip核实现。滤波器的系数用matlab产生并转成coe文件。 wire m_axis_data_tvalid; rcos_f…

官网下载JAVA的JDK11版本(下载、安装、配置环境变量)

目录 前言&#xff1a; 一、下载JDK11 1.先去浏览器搜索 2.选择Products 3.Java ​编辑 4.往下滑找到Oracle JDK,然后点击 5.往下滑找到Java11&#xff0c;再选择自己的操作系统 6.选择exe这个直接安装的后缀 7.跳出来的弹窗勾选&#xff0c;并点击 8.弹出来一个甲骨文…

树莓派4b linux内核调试(jtag、kgdb)

1、-O0编译树莓派4b linux内核(linux-5.10.95) 内核源码分支: https://github.com/raspberrypi/linux/tree/rpi-5.10.y 参考其他网站&#xff0c;注释掉arch/arm64/include/asm/jump_label.h文件里面的内联汇编分支&#xff1b; 修改arch/arm64/include/asm/memory.h里面的MIN…

大一学生Web课程设计 美食主题网页制作(HTML+CSS+JavaScript)

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

传奇开服教程——传奇微端架设教程-GEE引擎

登录器和网站配置好后&#xff0c;我们进入游戏后会发现是黑屏的&#xff0c;更新不了地图和NPC这些&#xff0c;因为还没有做微端&#xff0c;会黑屏也是正常的。 有些GEE版本有配套的微端程序&#xff0c;有些版本没有&#xff0c;需要自己去gee官网下载更新时间比引擎还靠后…

多层固定分组计算

【问题】 I want to build opening closing report – ITEM_TRANSACTION TABLE- Consider below data– 1.When item is prepared entry is made into table wih NULL indicator.. 2. When Item is issued/sold entry is made into table with ISSUE indicator Date Iname I…