How to sync a PRNG between C#/Unity and Python?

谁说胖子不能爱 提交于 2020-12-07 08:34:37

问题


I have a game implemented in Unity/C# that generates simple environments using the built-in PRNG (UnityEngine.Random). I am trying to reimplement the environment generation procedure in Python 3. I need the random number generators to be synchronized so that when provided with the same seed, the actual game in Unity and the Python reimplementation generate the exact same environment. What would be the best approach to synchronizing the two platforms?

Some solutions I have considered so far:

  • Attempt to reimplement Python's default random number generator (random) in C#. The source code is available, but fairly long so may difficult to implement in practice.
  • Attempt to reimplement UnityEngine.Random in Python. However, I don't have any source code, and even if I knew the class of PRNG used, there is no guarantee that I will be able to successfully reimplement it exactly the same.
  • Implement the same PRNG in both. However, I don't know what a good option for a PRNG is for my use case. I basically need something that looks random (though it doesn't have to be secure) and doesn't take more than an hour or two to put together. Wikipedia has a long list of PRNGs, and I have no idea the difficulty in implementing each of them.
  • Or maybe someone else has done this at some point...? I couldn't find anything online, though.

Any suggestions on the best approach, or a simple PRNG I can implement easily in both C# and Python?

Thanks!


回答1:


In general, the best way to "sync" PRNGs between two programs in different languages is to implement the same PRNG in both languages.

For your purposes, a linear congruential generator (LCG) is a simple PRNG if you only want "something that looks random (though it doesn't have to be secure)". This kind of generator is trivial to implement in both C# and Python.

One example, among many other possibilities, is the following 32-bit LCG (where x is the seed):

C#:

// Generate the next x from the current one.
unchecked {
    // NOTE: x is an `int`
    x = (0xadb4a92d * x) + 9999999;
}

Python:

# Generate the next x from the current one.
x = ((0xadb4a92d * x) + 9999999) & 0xFFFFFFFF

See section 8 of the very very recent paper by Steele and Vigna for other parameter choices as well as a review of the theory involving LCGs.

However, LCGs are far from perfect. (For instance, the above LCG produces x's with weak low bits, so that, e.g., every other x is odd and every other x is even.) And in general, LCGs, especially those with 32-bit seeds or other short seeds, are far from appropriate for many situations, including scientific work or information security. In case you want another choice for a PRNG, I list many of them.



来源:https://stackoverflow.com/questions/59829276/how-to-sync-a-prng-between-c-unity-and-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!