分享
三行代码  ›  专栏  ›  技术社区  ›  user11209806

如果有相同的参数,如何在PHP中生成相同的随机值? - How to generate same random values in php if they have same parameter?

php
  •  0
  • user11209806  · 技术社区  · 3 月前

    我使用一个函数来生成随机值,使用标记,包括参数作为长度、随机类型:字母、数字或混合,以及小写、大写。 现在这个问题是,我要存储或保存、修复或冻结一个随机结果,以便在多个地方使用它。 例如,我使用fixtrand而不是rand,那么只要标记具有相同的参数,整个页面的结果就会相同。

    给你一点我已经拥有的东西。当我使用一些标记(如[rand,10,a,u])时,它是完全功能性的,但每次都会生成随机值。我需要添加另一个标签来存储相同请求下相同结果的方式。

    function generateRandom($length,$type,$gen){
            switch ($type) {
                case 'A':
                    $rd= "";
                    srand((double)microtime()*1000000);
                    $data = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
                    for($i = 0; $i < $length; $i++){
                        $rd .= substr($data, (rand()%(strlen($data))), 1);
                    }
                    break;
                case 'N':
                    $rd= "";
                    srand((double)microtime()*1000000);
                    $data = '0123456789';
                    for($i = 0; $i < $length; $i++){
                        $rd .= substr($data, (rand()%(strlen($data))), 1);
                    }
                    break;
                case 'M':
                    $rd= "";
                    srand((double)microtime()*1000000);
                    $data = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789";
                    for($i = 0; $i < $length; $i++){
                        $rd .= substr($data, (rand()%(strlen($data))), 1);
                    }
    
                    break;
            }
            if ( $gen == 'U') $rd = strtoupper($rd);
            if ( $gen == 'L') $rd = strtolower($rd);
            return $rd;
        }
    
    $replaced_xxxxxx=str_replace("[MESSAGE]","$message",$replaced_xxxxxx);
    preg_match_all("/\[RAND,[0-9]+,[AMN],[LU]\]/",$replaced_xxxxxx,$random_tag_array);
            foreach ($random_tag_array[0] as $random_tag) {
                $random_stripped=$random_tag;
                $random_stripped=str_replace("[RAND,","",$random_stripped);
                $random_stripped=str_replace("]","",$random_stripped);
                $random_exploded=explode(',', $random_stripped);
                $random_generated=generateRandom($random_exploded[0],$random_exploded[1],$random_exploded[2]);
                $replaced_xxxxxx=preg_replace($random_tag, $random_generated, $replaced_xxxxxx,1);
    
    2 回复  |  直到 3 月前
        1
  •  1
  •   miile7    3 月前

    编辑 :正如@kikosoftware指出的,我的答案是 不真实随机 . 我修改了我的答案。现在使用 random_int() 密码保密的伪随机的。随机函数的结果现在与输入参数一起保存。这是唯一的方法,因为 随机变量in() 随机的。这样就无法再创建相同的值,因此必须保存这些值。

    这个解决方案需要更多的内存,因为它需要保存更多的值。但这是随机的。您可以在两种解决方案之间进行选择。如果你试图得到随机的例子,原始的解决方案就足够了。对于需要安全的事情(例如密码处理等),您应该使用新的解决方案。

    function generateRandom($length, $type, $gen){
        switch ($type){
            case 'A':
                $data = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
                break;
            case 'N':
                $data = '0123456789';
                break;
            case 'M':
                $data = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789";
                break;
            default: 
                $data = "";
                break;
        }
    
        static $randoms = array();
    
        $rd = "";
        $len = strlen($data) - 1;
        for($i = 0; $i < $length; $i++){
            if(!isset($randoms[$length.$type.$gen.$i])){
                $randoms[$length.$type.$gen.$i] = random_int(0, $len);
            }
            $rd .= $data[$randoms[$length.$type.$gen.$i]];
        }
    
        if ( $gen == 'U') $rd = strtoupper($rd);
        if ( $gen == 'L') $rd = strtolower($rd);
    
        return $rd;
    }
    

    原始答案 我想我会储存随机的种子。可以使用静态(或全局)变量,其中包含参数作为键,种子作为值。

    function generateRandom($length, $type, $gen){
        static $seeds = array();
        if(!isset($seeds[$length.$type.$gen])){
            $seeds[$length.$type.$gen] = microtime(true) * 1000000;
        }
        srand($seeds[$length.$type.$gen]);
        $rd = "";
    
        switch ($type) {
            case 'A':
                $data = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
                break;
            case 'N':
                $data = '0123456789';
                break;
            case 'M':
                $data = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789";
                break;
            default: 
                $data = "";
                break;
        }
    
        $len = strlen($data);
        for($i = 0; $i < $length; $i++){
           $rd .= $data[rand() % $len];
        }
    
        if ( $gen == 'U') $rd = strtoupper($rd);
        if ( $gen == 'L') $rd = strtolower($rd);
    
        return $rd;
    }
    

    此代码产生以下结果。我希望这就是你想做的:

    var_dump(generateRandom(3, "A", "L")); // prints e.g. string(3) "wkr"
    var_dump(generateRandom(4, "A", "L")); // prints e.g. string(3) "rppd"
    var_dump(generateRandom(4, "N", "L")); // prints string(4) "9377"
    var_dump(generateRandom(3, "A", "L")); // prints string(3) "wkr" again
    

    重新加载后,所有值再次不同(因为种子更改)。