-
-
Notifications
You must be signed in to change notification settings - Fork 262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ROT.RNG.setSeed unexpected behavior #184
Comments
Hi @nluqo, good finding! Thanks for the report.
Right, the
This is a problem indeed. I am open to fixing it, but we are facing a backwards compatibility issue - folks might be expecting a particular behavior for their already-generated seeds.
So, how about we add a seed-by-string feature that uses a better seeding mechanism and produces the desired avalanche effect? This would be a compatible change - and the documentation can mention that seeding with a string produces generally more robust results. I am, however, not sure how to properly implement the seeding with a string. The current RNG implementation (Alea) is based on the work at https://github.com/nquinlan/better-random-numbers-for-javascript-mirror. |
I'd put (pre-salt + the string + post-salt) through SHA-256 and then pull the least significant bytes to turn into a seed value. https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest The salt strings can be anything and don't need to be kept secret. PRE_SALT = "j2wAXcEUrFnZGpt9WsZE1RV4oNAOBcBO"
POST_SALT = "c5/0KcU6ad912gQ88c/53Ng+magf2x7P" |
The RNG uses four state values, though I am not sure how exactly is the |
Also, I would prefer the seeding process to be synchronous :-) |
Yeah, that'd be a good way to do it. |
Hmmm, in Node.js I'd use: And the browser I'd borrow Browserify's browser implementation of Node's crypto: These would give compatible synchronous strong hash functions. |
Sounds a bit like an overkill to me. We just need a way to convert a string to three 64bit values, without any particular crypto/security properties... how about the original Baagoe's Mash function? I would say this should have been used from the very beginning. |
Yeah, that's pretty cool. I'll bookmark this one. |
Ah yes, I forgot this even existed. Woops. Though I still think it should mention the sign of the number. I was using a library to generate SHA256 digests and getting an int out of it and it only returned signed integers... and thought I was good for a while. It's easy to test a couple times (positive input, negative input, positive input) and think "these all look different enough" but not realize all your negative inputs will degenerate to the same state.
Sounds good to me. It will change from the current behavior if you were misusing the API and passing a string, but I assume this is unlikely. |
I'm using
setSeed
for seeded runs in a game and was really surprised by the behavior. Two main issues:2.3283064365386963e-10
123
produces0.0599007117561996
and124
produces0.060387709410861135
. The numbers do diverge after that first uniform value, so it's probably easy enough to just throw away the first value?Perhaps these are known behaviors, but from the developer perspective I found them really confusing... and it's quite easy to write some broken randomness by not knowing it. Even some notes on the docs would help out a lot.
The text was updated successfully, but these errors were encountered: