尝试编写 8 位的可逆 PRNG,而不是密码
我正在尝试构建一个字节 PRNG,其中我可以获取一组字节(例如 10 或 15 字节)并返回一个种子列表,该种子列表将产生该字节列表。我不关心密码学,但它必须大致均匀分布,它必须击中所有可能的 2^8 组合,并且它必须偶尔能够重复一个数字而不被卡住。
问题是,我读过的大多数算法要么使用密码,这可能意味着它不允许重复,要么使用模数或非循环移位,这会导致损失并使反转函数充其量是不切实际的。此外,如果算法使用计数,则很难向后工作,因为字节列表输入不知道生成时内部 PRNG 的计数器是什么。
我意识到我正在寻找的是一种鱼与熊掌兼得的情况,但我想确保我没有错过其他解决方案。
在搜索时,我发现 这篇文章 具有类似的要求。我是用 C# 编写的,但实际上,语法并不重要。
我尝试自己编写的每个算法都是密码,因此无法重复和/或分布不均匀。我使用了反转、循环移位和种子掩蔽。
I'm trying to build a PRNG of bytes where I can take a set of bytes (say, 10 or 15 bytes) and return a list of seeds that would yield that list of bytes. I'm not concerned about cryptography, but it must be roughly uniformly distributed, it must hit all possible 2^8 combinations and it must occasionally be able to repeat a number without getting stuck.
The problem is, most algorithms I've read about either use ciphers, which probably means it won't allow repeats, or they use modulus or non-circular shifts that induce loss and make reversing the function impractical at best. Also, if the algorithm used counting, it would be hard to work backwards as the byte list input would not know what the internal PRNG's counter was at the generation time.
I realize what I'm looking for is a have-your-cake-and-eat-it-too situation, but I wanted to make sure there wasn't another solution I was missing.
While searching I came across this post which has similar requirements. I was writing in C# but really, syntax is not important.
Every algorithm I've tried to write myself has been a cipher and thus failed to repeat and/or not uniform in distribution. I used inversion, circular shifting and seed masking.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这有效吗?
由于它基于具有完整周期的线性同余生成器 (LCG),因此最终每个字节都将由每个种子生成。好像有重复的。并且它继承了底层LCG的一致性。
Does this work?
Since it is based on a linear congruential generator (LCG) with a full period, every byte will be generated by every seed, eventually. There seems to be repeats. And it inherits the uniformity of the underlying LCG.
我的顾问已将 PRNG(基于 L'Ecuyer 的 clcg4)修改为可逆的,以支持我们小组的 HPC 模拟工作。您可以在此处了解这些内容。
基本上,它“撤消”已完成的操作,并且正如您可能已经猜到的那样,这可能需要“撤消”随机数生成,然后沿着不同的计算路径再次重新生成这些相同的值。您可以在此处和此处。它是 BSD 许可的代码。
My advisor has modified a PRNG (based on L'Ecuyer's clcg4) to be reversible to support our group's HPC simulation efforts. You can read about these here.
Basically, it "undoes" what has been done and, as you may have guessed, this may require "undoing" random number generation and then re-generating those same values again along a different path of computation. You can look at this code here and here. It's BSD-licensed code.