用js实现, 梅森旋转生成随机数, 来代替Math.random();
该文章参考自 梅森旋转算法--伪随机数(加密、身份信息ID号)_Touch_Dream的博客-CSDN博客
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>梅森旋转法 生成随机数</title>
<style>
.chart{
width: 125px;
}
.chart-square{
float: left;
width: 20px;
height: 20px;
border: 2px solid black;
}
.red{
background: red;
}
.blue{
background: blue;
}
</style>
</head>
<body>
<input type="button" onclick="excuteFun();" value="生成随机数" />
<div id="chart" class="chart"></div>
<div style="clear: both;"></div>
<div id="msg" style="width:500px;word-break: break-word;"></div>
<script>
function excuteFun() {
var arr = [101, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 122, 130, 130,
201, 202, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207, 207, 208, 208, 208, 209, 209, 209, 210, 210, 210, 222, 230, 230
];
for(let i = 0; i < 1; i++) {
shuffle(arr);
}
render(arr);
let randomNumArr = [];
//设置种子
meisenRandom.srand(new Date().getTime());
for(let i = 0; i < 10; i++) {
let r = meisenRandom.rand();
randomNumArr.push(r);
console.log("随机数" + (i + 1) + "=" + r);
}
document.getElementById("msg").innerHTML = "生成的随机数: <br/>" + randomNumArr.join("<br/>");
}
function render(arr) {
var html = "用来洗牌,打乱顺序:<br/>";
arr.forEach(function(item) {
let color = "";
if(item < 199) {
color = "red";
} else {
color = "blue";
}
html += `<div class="chart-square ${color}"></div>`;
})
document.getElementById("chart").innerHTML = html;
}
function shuffle(arr) {
meisenRandom.srand(new Date().getTime());
for(let i = arr.length - 1; i >= 0; i--) {
let r = meisenRandom.rand();
let randomIndex = r % arr.length;
let itemAtIndex = arr[randomIndex];
arr[randomIndex] = arr[i];
arr[i] = itemAtIndex;
}
return arr;
}
/**
* 梅森旋转法 生成随机数
*/
let meisenRandom = (function meisen() {
let isInit = 0;
let index;
let MT = new Array(624); //624 * 32 - 31 = 19937
/**
* 设置种子
* @param {Number} seed
*/
function srand(seed) {
index = 0;
isInit = 1;
MT[0] = seed;
//对数组的其它元素进行初始化
for(let i = 1; i < 624; i++) {
let t = 1812433253 * (MT[i - 1] ^ (MT[i - 1] >> 30)) + i;
MT[i] = t & 0xffffffff; //取最后的32位赋给MT[i]
}
}
function generate() {
for(let i = 0; i < 624; i++) {
// 2^31 = 0x80000000
// 2^31-1 = 0x7fffffff
let y = (MT[i] & 0x80000000) + (MT[(i + 1) % 624] & 0x7fffffff);
MT[i] = MT[(i + 397) % 624] ^ (y >> 1);
if(y & 1) {
MT[i] ^= 2567483615;
}
}
}
/**
* 获取随机数
*/
function rand() {
if(!isInit) {
srand(new Date().getTime());
}
if(index == 0) {
generate();
}
let y = MT[index];
y = y ^ (y >> 11); //y右移11个bit
y = y ^ ((y << 7) & 2636928640); //y左移7个bit与2636928640相与,再与y进行异或
y = y ^ ((y << 15) & 4022730752); //y左移15个bit与4022730752相与,再与y进行异或
y = y ^ (y >> 18); //y右移18个bit再与y进行异或
index = (index + 1) % 624;
return y;
}
return {
srand: srand,
rand: rand
};
})();
</script>
</body>
</html>