I'm trying to calculate a sort or "daily random number" in a range, wich can't be guessed, for each user in our site but can't figure out how to do it.
I don't want a random number either, it must be a calculated number in PHP, not an additional database field or anything similar.
I tought at a function who can take the user's ID and the day of year and calculate this number.
Example:
USERID: 12345, Range: 0-7 (constant values for every user)
DayOfYear: 250 (change every day)
Then something like: ((12345 + 250) MODULO 8) (so I've range from 0 to 7 for each user). The problem is that the same number will come out every 8 days in a loop that user will find very fast.
Each user don't necessarly need a different number for every day, even the same number would be OK for a few days but not all users must have the same number. Also, most important, no loop scenario, so user can't guess his his daily number.
Thank you for your help.
There are so many answers to this question and none would be the best ... but I'm in a funny mood:
$id = hexdec(substr(md5($userId . date('z')), 0, 3)) % 8;
Use the md5-function to get a hex-string from a string. Then use a part of this string to calculate the mod 8.
For the next 10 days the id will be 5,7,5,3,6,0,2,0,2,4 when using your user id
But to guess a number between 0 and 7 isn't so hard, don't uses this for security ...
Related
I need to generate a random number within a given range. The number must be different for every new month of the year, and it should not be the same (although theoretically it is possible) as the number generated the year before for that given month.
I was thinking of using the php rand($min, $max) function in conjunction with date("w"), I am struggling with the part where I need to get different results for every year.
To illustrate what I mean, check this:
$numbers = range(1, 100); //our random array
echo $numbers[date("w")]; //date("w") returns number of week
There are 2 problems here: 1) it is not really random, 2) the number will be the same every year and 3) it does not reflect the whole size of the array as date("w") returns a number between 1 and 52.
Do you think this is accomplishable in pure PHP? Or do I need to make a cronjob for this?
Thank you for any help.
You could use every month the same number in the seed. Just to be clear the seed in the function srand ([ int $seed ] ).
You can do something like this:
srand(100);
echo rand();
and every time it returns the same number. So every month you can do something like this:
$min = 1;
$max = 100;
date_default_timezone_set('UTC');
$seed = date('Ym'); // it is the date as an integer
srand($seed);
echo rand($min, $max);
Pay attention to set the default time zone. If you don't, the result will depend to the server configuration.
-- UPDATE --
As #StevenSmith and #axiac stated you're not 100% sure the random generated number is unique.
In other words this means that wider the range (min-max) higher the probability you'll have every time a different number.
Use date('Ym') to generate an unique identifier for each (year, month) combination, use this value to initialize the pseudo-random generator's engine then generate one random number:
srand(date('Ym'));
$value = rand(1, 100);
Adjust the second line to match your needs. Now it generates an integer number between (and including) 1 and 100.
The value returned by date('Ym') is the same during a month. Every time you call srand() with a certain argument, the pseudo-random generator is reinitialized using that value and then it produces the same sequence of pseudo-random numbers when rand() is invoked (several times).
This ensures the generation of the same value for you during the entire month. During the next month and during the same month of the subsequent years the pseudo-random number generator is initialized with a different value and it generates a different sequence of pseudo-random numbers.
Depending on the values you use in your call to rand(), it might happen that the value returned by it this month is returned again in a different month. Use a large range for its $min and $max arguments to minimize this possibility.
You could generate a random number, select the closest multiple of 12, and then add the current month number.
For example, if the random number is 616, the closest multiple of 12 is 612. Add 0 (since it's currently January) giving you a final answer of 612. This will ensure that the number is unique for each month.
I'm working on a scratchcard script and I was wondering if someone could help me out, if you don't understand odds this may melt your brain a little!
So, the odds can vary: 1/$x; Let's say for now: $x = 36;
So here's what I am trying to understand...
I want to generate 9 random numbers between 1 and 5.
I want the odds of 3 numbers matching equivalent to 1/36.
It must be impossible to generate over 3 duplicate numbers at a time.
I can imagine an array loop of some kind would probably be the correct way of passage?
Sometimes - and this is one of those times - cheating is the best way to do what you want to do.
a) Set up an array of your 9 numbers, and a 2nd frequency array (5 elements) that counts which number occurs how often.
b) Generate a random number 1-5. Set the 1st and 2nd card to this number, and mark this number with 2 in your freqency array.
c) If random(36) < 1 (1/36 probability), set your 3rd card to the same number and mark this number with 3 in your frequency array.
d) Generate the rest of the cards - find a random number, repeat while frequency of the found number >=2, set the next card to number, increase frequency of the found number.
e) When finished, shuffle the cards (generate 2 random numbers between 1 and 9, swap the 2 cards, repeat 20-30 times).
Part d) is what i call cheating - you've put your 1/36 probabilty in step c), and in d) you just make sure you don't generate another match. e) is used to hide that from the user.
maybe I am trying something impossible, that's why I am asking :-)
I want to get 10 random numbers in specific range. But I want to specify key or hash by which would be these random numbers generated. So when ever I specify the same key, I will always get the same random numbers.
Is it possible, if yes, how ? Thanks for any help or hints.
Explanation: If is someone interested why I want to do this - it's for recipes site, where I want all day display exact same randomly picked recipes (day number = key) so they change every day, but stay the same all day long.
I would personnaly go for a stored version of what you are suggesting.
Every day, the first request made to the website will pick n random recipes and store them in the database, in a "recipe_by_days" table, containing the day (2013-09-16) and the list of picked recipes.
Then the next visitors will get the list just by querying that table with the day being today.
That made, it would be possible to list the randomly picked recipes that was out y days before.
But then, this implementation is useful if you want to keep the randomly picked recipes more than for today only.
Now if you are interested in just showing the same randomly picked recipes for the current day only, and not keep an history, you can then just add a column to your recipe table that can be null.
Every day, the first request will set this column to null, pick n random recipes, and update the column of theses to the current date.
The algo is quite simple :
Select the recipes that have "today_random" set to "today".
If none is returned (because they are in "yesterday" state) :
Set the column "today_random" from all the recipes to null
Pick n random recipes, update the "today_random" column of these to "today"
Return these selected recipes
else return the result
It looks like this post has the function you want:
http://www.php.net/manual/en/function.srand.php#90215
Just create an array of days, let's assume for week days, and just get the current day's recipies:
$recipies = array(
0 => array(...), // sunday
1 => array(...), // monday
2 => array(...), // tuesday
...
);
print_r($recipies[date("w")]); // current weekday's recipies
Then you can randomise for that particular array with array_shuffle or some other way.
This will consistently pick 10 random numbers between $lowerRange and $upperRange, based on a key:
mt_srand(crc32('your-key'));
$lowerRange = 100;
$upperRange = 200;
for ($i = 0; $i < 10; $i++) {
$choices[] = mt_rand($lowerRange, $upperRange);
}
print_r($choices);
I don't exactly know how to word this, so I am going to try my best at it. I am trying to make a constant out of a certain column within my database. What is it is a site where you can make reservations to certain events being held. Within the database there is a column for the maximum number of seats(num_seats) at the specific venue. On the website, it shows the max number of seat left/available(number subtracts when someone reserves a seat(s)). What I am trying to do, is at a certain number have the availability go from Available to Limited to None. The "None" part is easy, what I am looking for is the Limited. I want it to change to "Limited" when only about 1/3 of the venue is available.
Now, when the owner enters the number of seats(we'll say 100), the database populates with 100, so 1/3 would be roughly 34. My problem is, when a person register, the number goes down, so 99 = 33, 90 = 31, 80 = 26. It will always change, so if I say:
if($num_seats < $row['num_seats'] / .33) {
echo "Limited";
}
This will never be true since it always changes. My question(sorry for being "long-winded") is, is there of making the number a constant within my php code, or will it just be easier to add a new column to the database and have one named max_num_seats and the other name seats_avail?
Thanks in advanced...
Use two tables: one for the 'owner' where the total number of seats is stored and another for the reservations. Then do your join/select and figure out what to display.
I'm stuck with a small issue and don't want to generate my own algo for random number.
I've to Display 'word of the day' on website, it has to change only once per day and all data is stored in XML. At pageload I read xml file by simpleXml Parser in php and then generate a random number between 0, length of array and output a term + definition.
But i dont want it to change with every refresh, nor do I want to save it on server in database.
So how can I generate a random number between 0 to N, which would give same value for a span of 24 hours.
Just set the current date as Seed without hours, minutes and seconds.
srand(mktime(0, 0, 0));
$wordIndex = rand(0, $wordCount);
It will return the same number for one Day.
Option 1: No random numbers, just increase the index by one every day. It will look random enough since no one knows your file. If that is not good enough, randomize the input file (shuffle it once and safe it out again).
Option 2: Use today's date as the seed for the random number generator.
<?
srand(date("ymd"));
echo rand();
?>
If you dont want to store it, then use something, that is connected to daily cycle, for example, the date, or weekday.