Broken Random PHP - php

I have been using mt_rand(10,100) to get a random number between 10 and 100 but it gives me 74 every time.
Heres what im working with
$success=mt_rand(10,100);
Any ideas ? Do i need to seed somehow ? Thanks in advance.
---EDIT---
I have just tried this
srand(microtime());
$success=rand(10,100);
Still gives same answer every time, 47.
---EDIT---
this is the whole thing
srand(microtime());
$success=rand(10,100);
echo $success;
if ($success == 100) {
$displayline="You succeeded";
session_register("displayline");
header("location:userhome.php");
}

What version of PHP are you running? In 4.2.0, mt_rand() was changed to be seeded automatically.
You can seed it with mt_srand($seed), providing a seed value. I use the output of the microtime() function.
edit: Since you are on 5.2, check your code to see if mt_srand() is being called and comment out all such calls.

That's odd. If you do just mt_rand() what do you get? What's the value for mt_getrandmax()?
Try seeding it with mt_srand()

It seeds on itself.
http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbers/
Guess you should check your PHP version

Remove all the seeding functions and don't add them back in. Then restart your server.
Also, I found this PHP bug, which occurs on Windows systems with some versions of the php.ini file.

Related

PHP base_convert() function doesn't work over 6 byte

I'm programming a web app where you put a hex value in a field and the app give you the details of which bit are up.
But I'm facing a problem if a do:
base_convert(value,16,2)
with a 6 byte value I get the right bit correspondence, but if I do it again with 7 or more byte value I get a string that is not the right bit correspondence.
I don't know how to fix this problem since it's a PHP function.
Is there any alternative to this function in PHP?
You should work byte per byte instead of putting right away the full value in the base_convert() function.
please try this .
echo base_convert('value',16,2);
or
$test='value';
echo base_convert($test,16,2);
output: 10101110
ref: http://php.net/manual/en/function.base-convert.php

perl unary ~ gives not the expected result

I'm trying to port a php algorithm to perl but I struggle with one bit operator I'm not familiar with...
so the php code looks like this:
...
$var = '348492634';
print ~$var;
...
result: -348492635
doing the exact same thing in perl:
...
$var = '348492634';
print ~$var;
...
result: 18446744073361058981
I read a lot about the integer size depending on the architecture of the cpu, but I never found a working solution. Maybe I'm just using the wrong function in perl...
It's necessary for the logic to get same result as in the php script.
Thanks in advance
Seems that on your setup, PHP ints are 32bit signed while perl ints are 64bit unsigned.
This will probably do what you need on the given system but it is not guaranteed to work the same if you use it on another installation of perl.
$var = '348492634'; #hex!
print ~($var - 2**32) - 2**32;
The following will do for both $var='348492634' (which you claim to have) and $var=348492634 (which you did have):
unpack('l', ~pack('l', $var))
The quick and dirty conversion is:
print -($var+1); # like ~$var in PHP
If your perl is using 64-bit integers, this will only fail for $var=-18446744073709551616
(0x8000000000000000), which is a value you wouldn't use in 32-bit PHP anyway.

Memcached bug in PHP - binary protocol

I came across a bug using Memcached in PHP. Here's my piece of code:
<?php
$mc = new \Memcached();
$mc->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$mc->addServer("127.0.0.1", 11211);
$mc->touch("key", time() + 600);
$touchResult = $mc->getResultCode();
$mc->set("key", 1, time() + 600);
$setResult = $mc->getResultCode();
echo "<pre>";
echo "Touch result: $touchResult\n";
echo "Set result: $setResult\n";
echo "</pre>";
When you run this for the first time, this is the output:
Touch result: 16
Set result: 0
And for the second time forth:
Touch result: 0
Set result: 5
Correct me if I'm wrong but this is a bug right? Does anyone know a workaround for this?
Here are the versions I use:
Ubuntu 12.04 64bit
PHP 5.3.14
memcached 2.1.0 (PECL module)
libmemcached 1.0.8
Memcached sever 1.4.13
PS. If you wonder what the result codes mean, here they are:
0 RES_SUCCESS
5 RES_WRITE_FAILURE
16 RES_NOTFOUND
[UPDATE]
I played a little more with the code and found something even more interesting. This bug happens regardless of the key that touch and set are working on. As long as the touch operation returns 0 (which means it was successful) the set operation will fail.
[UPDATE]
I managed to produce some other errors as well. e.g. acquiring some key from server and then adding some other will also lead to nasty problems (RES_END code). I believe all these problems are somehow related to binary protocol. It seems to me as if binary protocol's implementation is hardly near stable. Operations which can work without binary protocol will do just fine but once the protocol is set to binary, they will result in blocking problems.
All right.
In first time, you touch not existed key - result is RES_NOTFOUND. When you do set - you write value success - RES_SUCCESS.
In next time you touch existed key (you set it in first linch) and get result of operation RES_SUCCESS, next you try set value for existed key - result false. All right.
If you want change existing value you must use Memcached::replace() method instead of "set"

regain constant pseudo-random in PHP 5.2

I am including the same "random.inc" in foo.php and bar.php. For each, I want reproducible "random" results.
So in foo.php I always want one set of numbers and/or keywords. In bar.php another. Which shouldn't change on reload. That's what I mean by contant pseudo-random. And that's why I seeding on the url. However I still get different results for individual numbers as well as for array pickson every reload. This is the full php file:
<?
header('Content-Type: text/plain');
$seed = crc32( $_SERVER['REQUEST_URI'] );
echo "phpversion: ".phpversion()."\nseed: $seed\n";
srand( $seed ); // (seed verified to be contant as expected)
// neither single values nor array pics turn out deterministic
echo ''.rand(0,100).' '.rand(0,100).' '.rand(0,100)."\n";
$values = array( '0'=>21,'1'=>89,'2'=>96,'3'=>47,'4'=>88 );
print_r( array_rand( $values, 3 ) );
?>
In the days of PHP4.1 it was (verified) possible to achieve constant pseudo-random like this. array_rand API documentation describes as a feature that since 4.2 initialization happens automatically. Perhaps this is overriding any explicit seeding? (if so, perhaps explicit seeding should raise an internal PHP flag, preventing automatic seeding?). Btw: mt_srand() and srand() are equally not working.
I would really like to get my deterministic / constant pseudo-random back...
Update: Solution below (Windows and/or version 5.2 's fault)
Works for me (PHP/5.3.6):
<?php
$data = range(1, 100);
srand(1);
print_r(array_rand($data, 3));
... always prints:
Array
(
[0] => 21
[1] => 89
[2] => 95
)
... in my machine. Apparently, the exact numbers differ depending on the exact environment but they're reproducible.
Guys, you are all correct! (Sorry, I answer it myself now)
my web hoster runs 5.2.17 under Linux 2.6.36, and above problem exists.
under Win x64 5.3.0 everything works as expected.
So it's everyone's guess if that's an OS related bug and/or a PHP bug, fixed in 5.3.0.
Given that random constant seeding worked before, I am guessing they fixed in 5.3 the bug that came with the autoseed feature enhancement in 4.2. Anyway, Thanx again, at least there's clarity now.
The seeding functions are still available, and should still work; it's just since PHP 4.2 they are automatically seeded with the time on page load; but you can still call them to reset the random sequence to a known starting point.
[edit] I have just done a quick test program to make sure I wasn't imagining it!
mt_srand(50000);
print "rand="+mt_rand(0,10000);
Using PHP 5.2, this always results in the same value being printed (1749).
[EDIT]
As noted by #cwd and in the accepted answer to this question, there appears to be a discrepancy in PHP 5.2's behaviour with random number seeding between the Linux and Windows versions. In PHP 5.2 on Linux, the above technique does not appear to work.
Fortunately, the bug seems to have been fixed in PHP 5.3, so the solution to this problem is simply to upgrade. (PHP 5.2 is not supported any longer, so you should upgrade anyway)
Btw, if anyone else wants "constant windows-pre-5.3 pseudo-random" (of low quality, e.g. for stuff like SEO buzzwording) this is a tested workaround:
$r = abs(crc32($URL))%20; // a number between 0 and 19, based on URL
In PHP 5.2.17 and probably on all versions of PHP 5.2, (not sure about windows), we lose the capability of generating random numbers based on a seed as PHP changes the algorithm used for random numbers.
rand and mt_rand are "broken" not only because they will not give one random number, but they will also not give a same sequence of random numbers - even when using a seed!
At first the PHP developers tried to argue that this is the way that it "should" work, but we can guess they caught enough grief about the problem that they have reverted the way that it works with PHP 5.3.
See the php mt_rand page and the bug tracker to learn about this issue.

How can I compare MySQL Versions in PHP?

Okay, so I'm getting my MySQL Version like so:
preg_replace('#[^0-9\.]#', '', mysql_get_server_info());
Which gives me a number like: 5.1.36
That's all good. What I need to do, is compare that version with another version. I was about to attempt to write my function to compare them, when I thought of version_compare(). However, upon testing I became unsure, but perhaps I'm just not sure how MySQL Version Numbers work.
This is what I tested:
version_compare('5.1.36', '5.1.4', '<');
or
5.1.36 < 5.1.4
I assumed that this would return true, that 5.1.36 is less than 5.1.4. My reason for that is, I figure 5.1.4 is actually 5.1.40 not 5.1.04. Perhaps I'm wrong there.
So am I thinking wrong, or is the function returning the incorrect result?
The function is correct. The numbering system is M.m.r where each "number" is a decimal number.
M is the major version number
m is the minor version number
r is the revision number
So 5.1.36 would be revision 36 of the 5.1 minor version... Therefore, 5.1.4 would be revision 4 (and hence 36 > 4)...
http://php.net/version_compare :)
http://www.php.net/manual/en/mysqli.get-server-version.php
mysqli's get_server_version() method will return the version as an integer.
main_version * 10000 + minor_version
* 100 + sub_version (i.e. version 4.1.0 is 40100).
I assumed that this would return true,
that 5.1.36 is less than 5.1.4. My
reason for that is, I figure 5.1.4 is
actually 5.1.40 not 5.1.04. Perhaps
I'm wrong there.
Yes, 5.1.36 is greater than 5.1.4.

Categories