【问题标题】:PHP number between an interval depending on input string间隔之间的 PHP 数字取决于输入字符串
【发布时间】:2016-06-17 07:43:14
【问题描述】:

在 php 中我可以这样做:

echo rand(5, 15);

它会给我一个介于 5 到 15 之间的数字,每次都不一样。

取决于输入字符串的静态数

echo my_static_number(5, 15, 'some/custom_string');

我仍然想要一个介于 5 到 15 之间的数字。不同之处在于我希望根据第三个参数(一个字符串)来计算它。

  • 允许的输出编号 5、6、7、8、9、10、11、12、13、14、15
  • 只要函数调用保持不变,每次都使用相同的数字。

现实生活中的例子

文件夹中的图片:

1.jpg
2.jpg
3.jpg
etc.

php 调用:

<img src="<?php echo get_image(1, 15, $url); ?>">
<img src="<?php echo get_image(1, 15, $url); ?>">

输出如下:

<img src="7.jpg">
<img src="7.jpg">

只要函数调用相同,每次相同的数字。

【问题讨论】:

  • 您可以调用rand() 函数,然后使用唯一标识符保存返回的号码(例如您的$url),然后在另一个rand() 调用之前,您可以检查,如果这个兰特已存在号码。
  • 这项工作应该在一般基础上工作还是只在脚本执行时工作?
  • @Yoshi 它不应该在不同的执行中产生不同的结果。如果带参数的函数调用相同,则结果相同。
  • @JensTörnell 我认为您正在寻找某种散列函数。你为什么不改用它呢?
  • @silkfire 而不是什么?但是,是的,很好的答案已经出现,它们是基于哈希的。 :)

标签: php string intervals


【解决方案1】:

我希望您正在构建负载平衡器。

您需要从字符串中计算出hash 并将其转换为数字。一个好的伪随机散列函数足以让你得到一个随机分布。一种解决方案可能是这样的:

function my_static_number($a, $b, $str) {
    $hash = hash('crc32', $str); // crc32 is probably the fastest here
    $dec = hexdec($hash); // convert hash to a decimal value
    $base = $b + 1 - $a; // +1 is needed to include $b as possible value
    return $a + fmod($dec, $base); // get remainder from $dec / $base
}

teh playground的一些测试:

更新:如果您先使用 $hash 的前 2 个字符,然后使用 $dec % $base 而不是 fmod,则速度可能会略有提高:

function my_static_number($a, $b, $str) {
    $hash = substr(hash('crc32', $str), 0, 2); // effectively produces a number between 0 and 255
    $dec = hexdec($hash);
    $base = $b + 1 - $a;
    return $a + $dec % $base;
}

我对随机分布进行了测试,两个函数都可以reasonably well

【讨论】:

  • 试过了。效果很好!有什么陷阱吗?
  • 我认为如果你只取$hash的前2个字符然后你可以使用基于整数的余数:$dec % $base而不是fmod,它可以提高速度。那应该会快一点。至于随机性——理论上应该是随机的,但我没有进行适当的测试。
【解决方案2】:

当我读到你的问题时,我是这么想的:

function my_static_number($min,$max,$seedStr)
{
  $hash   = md5($seedStr);
  $length = strlen($hash);
  $seed   = 1234;
  for ($i=0; $i<$length; $i++) $seed += ord($hash[$i]);
  srand($seed);
  return rand($min,$max);
}


echo my_static_number(5, 15, 'some/custom_strings');

rand() 可以播种,使用相同的种子会生成相同的随机序列。所以我对完整的字符串进行哈希处理,将该哈希的 ascii 值相加,并将其用作种子。

所以你会得到随机数,但它们对于相同的种子字符串是相同的。

这个函数确实有一些限制:

  • 速度:不是最快的。如果需要,您需要一个完全不同的算法。
  • 随机性:由于种子值数量有限,输出的随机性略有下降。这可以改进。

想一想:这里没有真正需要使用任何随机函数:您可以使用哈希来计算半随机数。像这样:

function my_static_number($min,$max,$seedStr)
{
  $hash   = md5($seedStr);
  $length = strlen($hash);
  $number = 1234;
  for ($i = 0;$i < $length;$i++) $number += ord($hash[$i]);
  return $min + ($number % ($max-$min));
}

echo my_static_number(5, 15, 'some/custom_string');

【讨论】:

  • 您可以使用crc32 从字符串中生成整数哈希。
  • 有效!伟大的!如果您有时间并且愿意,可以尝试哈希计算。更新:其他解决方案即将推出,也会尝试它们。
  • 好吧,我找到了某个地方,不是吗? :-)
  • @KIKOSoftware 到目前为止,我认为 Ruslan 版本真的很难被击败。
  • @Jens Törnell:是的,使用 crc32 的十六进制结果并将其转换为十进制的技巧非常好。基本思想是一样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-18
  • 2018-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-12
相关资源
最近更新 更多