1

我想要一种方法来获取任何输入(url)并取回 1-4 之间的数字,尽可能均匀地分配 25% 的任何输入。重要的是它每次都获得相同的值 1-4。

我想要这样做的原因是,我可以为 CDN 的一组 CNAME(子域)创建看似随机且受干扰的内容。它会拍摄最初的照片www.website.com/picture.png并将它们输出为

cdn1.website.com/picture.pngcdn2.website.com/picture.pngcdn3.website.com/picture.pngcdn4.website.com/picture.png

有效地让我绕过对子域设置的浏览器限制,给我更多的并行连接(阅读更多:http: //yuiblog.com/blog/2007/04/11/performance-research-part-4/)。我希望 URL始终传递回特定 CDN 的原因是出于缓存目的;如果第www.website.com/picture.png一次显示为as 然后cdn1.website.com/picture.png第二次显示为 ascdn2.website.com/picture.png那么浏览器将不知道它已经在 cdn1 下缓存了相同的图片,并且会下载相同的图片两次,而不是依赖缓存。


这里是建议的 php,但我从结果中可以看到,对于小样本集,我没有得到我想要的 25% 的比率。我正在寻找对于小样本也有接近 25% 分布的替代方案。

<?php

$num_array = array();
for ($i = 1; $i <= 10000; $i++) {
    $num_array[]=(crc32(genRandomURL()) % 4)+1;
}


print "<pre>";
print_r(array_count_values($num_array));
print "</pre>";

$num_array = array();
for ($i = 1; $i <= 10; $i++) {
    $num_array[]=(crc32(genRandomURL()) % 4)+1;
}


print "<pre>";
print_r(array_count_values($num_array));
print "</pre>";


function genRandomURL($length = 10) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
    $string = "";
    for ($p = 0; $p < $length; $p++) {
        $string .= $characters[mt_rand(0, strlen($characters))];
    }

    return "http://www.website.com/dir/dir2/dir3/".$string.".png";
}


?>

结果:

Array
(
    [3] => 2489
    [1] => 2503
    [2] => 2552
    [4] => 2456
)
Array
(
    [1] => 5
    [2] => 1
    [3] => 3
    [4] => 1
)
4

1 回答 1

0

如何创建名称的哈希,获取该哈希的最后两位,然后最终将它们转换回十进制数。只要您的名字没有改变,就应该返回相同的值。

function img_id($string){
    $hash = md5($string); // create hash
    $bin_hash = base_convert($hash, 16, 2); // convert to binary
    $last_bits = substr($bin_hash, -2); // get last two bits
    $img_int = bindec($last_bits)+1; // turn bits to integer, and + 1
    return $img_int; // will be number from 1 to 4
}

$picture = 'picture.png';
$cdn_id = img_id($picture);
$url = "cdn{$cdn_id}.website.com/{$picture}";

如果您的名字可能会更改,那么您还可以查看对实际文件内容进行哈希处理。

于 2013-07-06T20:38:48.393 回答