[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit

Permalink
Revert "Fix #71152: mt_rand() returns the different values from origi…
Browse files Browse the repository at this point in the history
…nal mt19937ar.c"

This reverts commit 6f6bd8c.

`mt_rand()` is seedable with `mt_srand()` which means it can be used to (re)produce specific streams of numbers. All code (no matter how few instances that may be) that previously depended on this behaviour will no longer produce the same results.

This kind of change needs to be discussed before being committed.
  • Loading branch information
lt committed Feb 18, 2016
1 parent aa383d6 commit a0724d3
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 54 deletions.
2 changes: 1 addition & 1 deletion ext/standard/rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ PHPAPI zend_long php_rand(void)
#define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */
#define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */

#define twist(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((php_uint32)(-(php_int32)(loBit(v))) & 0x9908b0dfU))
#define twist(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((php_uint32)(-(php_int32)(loBit(u))) & 0x9908b0dfU))

/* {{{ php_mt_initialize
*/
Expand Down
53 changes: 0 additions & 53 deletions ext/standard/tests/math/mt_rand_value.phpt

This file was deleted.

43 comments on commit a0724d3

@andreasdotorg
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Sure it's broken, but at least it's consistently broken!"

@lt
Copy link
Contributor Author
@lt lt commented on a0724d3 Feb 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are appropriate channels to discuss whether or not it is fundamentally broken or simply non-standard. You don't break userland code without those discussions.

@lolphp876
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is fundamentally broken if you claim to implement an specific algorithm in a "non-standard" way that produces different of output. If you want to implement a different algorithm, call it by another name. This is why the PHP development team isn't taken seriously; they disregard proper knowledge of their profession in a cavalier way, lacking basic reading comprehension, due diligence and sanity.

@salathe
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is broken, since the values don't match what is in mt19937ar.c. That's not in question.
Changing the (mis)behaviour without discussion: that is what's questionable here.

@laruence
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@it @salathe the pull request has been there for monthes.. I don't understand why you don't give the idea then, now complaint it was committed without discussion? (with whom? with you?)

@lt
Copy link
Contributor Author
@lt lt commented on a0724d3 Feb 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@laruence I don't normally look through commits for breaking changes because normally they hit the mailing list. I just happened to see this yesterday.

It's a breaking change. It definitely does not belong in the 7.0 branch.

You may, as you state on the PR, find it weird that people might rely on a predictable stream of pseudo-random numbers, but they do have their uses.

@laruence
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@it okey, thanks, then may ,as this is really typo, leave the fix in master, and add a note in changlog, it is much better then only reverting this, thanks

@salathe
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@laruence I want to see this change (not the revert), don't get me wrong. With my documentation hat on, a heads up wouldn't go amiss.

As for why comment now? I don't watch the php-src PRs, so missed it there and only came now as it was linked in a place I do watch. Sorry if that's not good enough for you. That said, I did see the original commit (not the revert) email, and inwardly applauded the change.

@Hypfer
Copy link
@Hypfer Hypfer commented on a0724d3 Feb 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lt "You may, as you state on the PR, find it weird that people might rely on a predictable stream of pseudo-random numbers, but they do have their uses."

I'd like to know a use case in which someone would rely on that. Just out of curiosity.

@Two9A
Copy link
@Two9A Two9A commented on a0724d3 Feb 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to know a use case in which someone would rely on that. Just out of curiosity.

Maze generation is one example: if you want "levels" of maze, a simple way to do that is to seed the RNG with a particular number that generates a subjectively "easy" or "difficult" maze. The seeds then correspond to the level numbers, reducing storage of the level information by orders of magnitude.

@WolleTD
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case your code needs a reproducable sequence of pseudo-random numbers, why not just hash your seed? If you need more numbers, hash the resulting hash (and so on). They will never change, not even when changing the environment/language/whatsoever.

Relying on the predictability of a pseudo-random number generator looks like bad style for me.

@koraa
Copy link
@koraa koraa commented on a0724d3 Feb 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case your code needs a reproducable sequence of pseudo-random numbers, why not just hash your seed? If you need more numbers, hash the resulting hash (and so on). They will never change, not even when changing the environment/language/whatsoever.

Wouldn't you then just write your own hash-based PRNG?
PRNGS are standardized, just as hash functions are. Why would the latter be less prone to typos than the former?

@WolleTD
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@koraa You're right, you would.
But if PRNGs are standardized, shouldn't we get PHPs PRNG to that standard?
Ok, well, we should keep providing the old one, that's right.

@Profpatsch
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pure internet gold. Don’t ever change, PHP team. We need some fun in our lives.

@yetzt
Copy link
@yetzt yetzt commented on a0724d3 Feb 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please leave it broken, so i can continue pissing on about how bad php is.

@gries
Copy link
@gries gries commented on a0724d3 Feb 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use this procedure for the next security fixes if somebody comes up with an obscure use case that relies on a security bug. :D

Also:
The public api does not change,
the method is still producing the results as expected and as described in the documentation,
and
http://php.net/manual/en/function.mt-srand.php even mentions that its NOT SAFE to rely on the sequences.

@tehplague
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

< irony >
This was by far the best idea ever - to further encourage people to count on the predictability of so-called "random numbers"
< /irony >

Feels like re-inventing register_globals because that's what people were used to.

@hikari-no-yume
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've backported the mt_rand_value.phpt test so that we actually have tests checking what mt_rand outputs. However, the backported version tests that it always produces the wrong result:

a50c31d

@FSMaxB
Copy link
@FSMaxB FSMaxB commented on a0724d3 Feb 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This discussion makes it seem like some people think that this is a random number generator for cryptographic purposes, but it's not. So stay calm.

@KiNaudiz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I don't use PHP.

...

Well, it's part of the reason.

@MercSec
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Andreas ist right and there no "other Channels".. it's fucked up.
"There are appropriate channels to discuss " : No... it's brocken. Thanks...

@torvitas
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, at least there are laughs all throughout germany now: http://blog.fefe.de/?ts=a83b3c21

@hikari-no-yume
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's a buggy implementation, but we can't fix this in a patch release, there's a risk of backwards-compatibility breakage. It doesn't really matter if it doesn't match Mersenne Twister to existing apps. They just care if it works predictably. If we suddenly fix it in a patch release, we might break existing apps.

@PurHur
Copy link
@PurHur PurHur commented on a0724d3 Feb 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You break shitty code... I dont think this is a problem if the other code will work even better.

@hikari-no-yume
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, what? Expecting the RNG to work predictably is reasonable behaviour.

@mhotchen
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just want to show my appreciation for the language maintainers here as a very heavy user of PHP and part of a team that maintains a huge amount of legacy code. I'm glad that I can continue to allow security and other non-BC changing updates to happen automatically and I can check the change logs only when doing major version updates. I need this level of stability and maturity in a language instead of having small things subtly break in code I've never read and don't understand and me wasting days wondering why, or weeks trying to rewrite, all while the business continues to suffer.

@PurHur
Copy link
@PurHur PurHur commented on a0724d3 Feb 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect diffrent values...

@dequis
Copy link
@dequis dequis commented on a0724d3 Feb 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see some people in this thread don't even understand the difference between a CSPRNG and mersenne twister and are just here to repeat that meme that "php is bad" without even understanding what the issue really is about.

Hint: it's not security sensitive, and the reverted fix didn't make the generated sequences any less predictable. That's not even relevant.

@m0yellow
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could break legacy code.
I would rather say show that this kind of code really exists. code search, guides, whatever. This would be such a legacy code that might even break when changing platforms 32->64bit.
Otherwise, thanks for maintaining such a large codebase, and just fix it right by applying the patch.

@hikari-no-yume
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we don't know. Most code isn't open-source.

Also, another possible thing that will break is unit tests.

Though using GitHub and Open Hub Code Search, I couldn't find a single non-phpt usage of mt_srand. I could find usages of srand, but they all seem to use microtime.

@yohgaki
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MT rand should be "MT rand" otherwise it is not MT rand simply.
Anyway, I sent mail to internals. Let's discuss what we should do for released versions there.

@divinity76
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least, remember to fix it in 7.1.

inb4 "php_mt_rand()" polyfill

@DarkMukke
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are "depending" (quoting the original comment here) on 'random', you are doing it wrong. Random should be unexpected, therefore undependable.

@hikari-no-yume
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For backwards compatibility purposes, generally what matters isn't whether you ought to depend on something, but whether existing code actually does.

@DarkMukke
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But how much do you want to keep functionality just for BC and sacrifice fundamental fixes.
Its it worth not making progress in a better code base, because it might break your ancient code ?
Just add it to the list http://php.net/manual/en/migration70.incompatible.php

@yohgaki
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Randomness of PHP mt_rand() is verified and it's supposed to be the same quality as original one. Games need the same random sequence on occasions, for example. If we are going to "fix" this, we should have INI switch for this. BTW I'm +1 for fixing this.

@nikic
Copy link
Member
@nikic nikic commented on a0724d3 May 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, someone is already working on an RFC which will fix this issue, as well as a slew of other problems with the non-cryptographic PRNGs in PHP.

@hwkns
Copy link
@hwkns hwkns commented on a0724d3 May 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are probably children out there holding down spacebar to stay warm in the winter!  YOUR UPDATE MURDERS CHILDREN.

@tom--
Copy link
@tom-- tom-- commented on a0724d3 Jun 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added side-by-side BigCrush test results for MT19937 and mt_rand() to this gist.

@sammcbride
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just add a behavior flag to the end that defaults to the original value? Won't that solve everyone's problem?
mt_rand(min, max, usef*upresult = true);
If you want the new way, set it to false or name the parameter the inverse, etc. Whatever makes everyone happy.

@hikari-no-yume
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you come here to comment on an old commit, to suggest something that was done years ago? Please don't.

@tom--
Copy link
@tom-- tom-- commented on a0724d3 Aug 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sammcbride

Why not just add a behavior flag to the end ...?

It makes no sense to switch algorithm on a per-fetch basis so the algorithm is set by mt_srand().

@David263
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All sorts of problems have been suggested for mt_rand. A good cryptographic-strength alternative is:
$bytes = random_bytes(4); // Choose desired number of bytes of precision
$hex = bin2hex($bytes);

Please sign in to comment.