js版梅森旋转生成随机数

用js实现, 梅森旋转生成随机数, 来代替Math.random();

该文章参考自 https://blog.csdn.net/Touch_Dream/article/details/68948708

<!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>

猜你喜欢

转载自blog.csdn.net/cxgasd/article/details/81139769