javascript - 如何让这个 PRNG 生成范围内的数字?
问题描述
我在下面找到了这个,用于 JavaScript 中的 8 位和 16 位数字:
const fetch = (x, o) => {
if (x >= o) {
return x
} else {
const v = (x * x) % o
return (x <= o / 2) ? v : o - v
}
}
const fetch16 = (x) => fetch(x, 65519)
const fetch8 = (x) => fetch(x, 251)
// the last number can be anything.
const build16 = (x, o) => fetch16((fetch16(x) + o) ^ 42703)
const build8 = (x, o) => fetch8((fetch8(x) + o) ^ 101)
let i = 0
let invalid = []
while (i < 255) {
let j = 0
while (j < 255) {
let x = build8(i, j)
if (x > 255) {
invalid.push([ i, j, x ])
}
j++
}
i++
}
console.log(JSON.stringify(invalid))
然而,虽然fetch8
andfetch16
函数在重复之前正确地循环遍历整个数字集,但build8
andbuild16
函数却没有,它们超出了所需的范围,请参见上述代码的输出。例如,当i = 11
和j = 184
,x = 340
,即> 255
。
但是,这些函数的输出非常棒build8
。build16
它看起来完全是随机的,并且在遍历整个集合之前不会重复任何值。
我如何修改这些build8
和build16
函数,使它们只包含集合中的数字(0-255 或 0-65535),但像这里一样看起来完全随机,但在遍历所有这些之前从不重复一个值?
我不完全确定这篇文章的作者是如何登陆的fetch8((fetch8(x) + o) ^ 101)
,例如,执行 XOR 并传递这样的值。但最终结果显得非常随机。我只是想这样做,所以输出是:
- 在所需的值范围内。
- 在枚举所有值之前不重复任何值。
- 看起来像 build8 一样完全随机。
解决方案
您超出范围值的原因是,虽然fetchXX
会产生范围内的值,但会+ o
破坏此属性。XOR 操作有时可能会将其带回范围内,但并非总是如此。
因此,您应该对 之后的值取模+ o
。XOR 操作永远不会使其超出范围,因此可以保持原样。
其次,要测试是否没有生成重复项,您需要修复传递给buildXX
函数的两个参数之一,只改变另一个。冻结第二个论点对我来说似乎更合乎逻辑。
所以这就是它的样子:
const fetch = (x, o) => {
if (x >= o) {
return x
} else {
const v = (x * x) % o
return (x <= o / 2) ? v : o - v
}
}
const fetch16 = (x) => fetch(x, 65519)
const fetch8 = (x) => fetch(x, 251)
// the last number can be anything.
const build16 = (x, o) => fetch16((fetch16(x) + o) % 65536 ^ 42703)
const build8 = (x, o) => fetch8((fetch8(x) + o) % 256 ^ 101)
const j = 115; // If you don't want duplicates, either i or j should stay fixed
let i = 0
let invalid = [];
let valid = new Set;
while (i <= 255) { // <-- small fix here!
let x = build8(i, j); // To test, you can swap i and j here, and run again.
if (x > 255) {
invalid.push([ i, j, x ]);
} else {
valid.add(x);
}
i++;
}
console.log("invalid:", JSON.stringify(invalid));
console.log("count of valid:", valid.size);
推荐阅读
- google-app-engine - GCP kms 加密环境变量并通过 cloudbuild.yaml 将加密密钥传递给谷歌应用引擎
- javascript - 找到流浪号码
- javascript - 使用列选项“order”的引导表列默认排序
- php - 如何在php上创建html标签结构
- java - GWT 应用程序未实现前端更改
- javascript - 如何使用 Javascript 从 tr 获取第一个 td 值?
- html - 如果未找到 ID,如何默认 SVG 精灵
- javascript - 使用 javascript UDF 在 BigQuery 中对整数数组的值求和
- python - 在 pandas 中按组连续获得最长连续周数
- jquery - 未捕获的类型错误:无法读取 null 的属性“按钮”