【问题标题】:Generate random number that changes every month生成每月变化的随机数
【发布时间】:2017-01-25 21:36:44
【问题描述】:

我需要在给定范围内生成一个随机数。该数字必须在一年中的每个新月份都不同,并且它不应与该给定月份的前一年生成的数字相同(尽管理论上这是可能的)。

我正在考虑将 php rand($min, $max) 函数与 date("w") 结合使用,我正在努力解决每年需要获得不同结果的部分。

为了说明我的意思,请检查:

$numbers = range(1, 100); //our random array
echo $numbers[date("w")]; //date("w") returns number of week

这里有两个问题:1) 它不是真正随机的,2) 每年的数字都相同,3) 它不反映数组的整个大小,因为 date("w") 返回一个数字介于 1 到 52 之间。

你认为这在纯 PHP 中可以实现吗?还是我需要为此做一个 cronjob?

感谢您的帮助。

【问题讨论】:

  • 不能把随机生成的数字存起来,每个月生成一个新的吗?
  • 是的,我可以这样做,但我想知道是否有办法不存储它。也许这有点疯狂;)
  • 原理很简单:对date('Ym')的值进行哈希运算。这为您提供了一个与当前月份唯一相关的所有意图和目的的随机值。哈希通常会产生一个十六进制或二进制值,因此您只需将其基本转换为十进制。要将其限制在一定范围内,请应用模数等操作。
  • 我喜欢散列的想法,确实很有用,谢谢!
  • 能否生成一个随机数,选择最接近的 12 倍数,然后加上当前月份数?例如,如果随机数是 616,则 12 的最接近的倍数是 612。加 0(因为是 1 月)给你的最终答案是 612。

标签: php random


【解决方案1】:

您可以在种子中每个月使用相同的数字。只是为了清除函数srand ([ int $seed ] )中的种子。

你可以这样做:

srand(100);
echo rand();

并且每次它返回相同的数字。所以每个月你都可以做这样的事情:

$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);

注意设置默认时区。如果不这样做,结果将取决于服务器配置。

-- 更新--

正如@StevenSmith 和@axiac 所说,您不能100% 确定随机生成的数字是唯一的。 换句话说,这意味着范围越宽(最小-最大),您每次获得不同数字的概率就越高。

【讨论】:

  • 哇,这是一些沉重的东西,有趣的解决方案,一定会检查出来的!
  • @freedev,以这种方式设置种子是否保证每个月都会给出一个唯一的数字?
  • @SteveSmith 好吧,对不起,不是唯一的。随机的。这意味着如果范围足够宽,您几乎可以肯定它每次都返回不同的数字。当我写下答案时,我意识到了不同之处。
  • @freedev 设置种子将保证相同的数字,但 AFAIK 没有什么可以阻止相同的数字出现两次不同的种子。
【解决方案2】:

使用date('Ym')为每个(年、月)组合生成一个唯一标识符,使用该值初始化伪随机生成器的引擎,然后生成一个随机数:

srand(date('Ym'));
$value = rand(1, 100);

调整第二行以满足您的需要。现在它会生成一个介于(包括)1 和 100 之间的整数。

date('Ym') 返回的值在一个月内是相同的。每次使用特定参数调用 srand() 时,伪随机生成器都会使用该值重新初始化,然后在调用 rand() 时(多次)生成相同的伪随机数序列。

这可确保在整个月内为您生成相同的值。在下个月和随后年份的同一月份,伪随机数生成器被初始化为不同的值,并生成不同的伪随机数序列。

根据您在调用rand() 时使用的值,它本月返回的值可能会在不同月份再次返回。对其$min 和$max 参数使用较大的范围以尽量减少这种可能性。

【讨论】:

  • 感谢您的回答,我喜欢您和@freedev 的解决方案。会调查的。
【解决方案3】:

您可以生成一个随机数,选择最接近 12 的倍数,然后添加当前月份数。

例如,如果随机数是 616,则 12 的最接近的倍数是 612。加 0(因为现在是 1 月)给您的最终答案是 612。这将确保每个月的​​数字都是唯一的。

【讨论】:

  • 这要求您将该号码保存在某处,否则您将无法在整个月内重复使用它。如果您要在任何地方保存数字,有更简单的方法来确保唯一性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多