如何在PHP中生成具有3位数字且每个数字中没有双精度数字的唯一数字

如何在PHP中生成具有3位数字且每个数字中没有双精度数字的唯一数字,php,random,numbers,generator,Php,Random,Numbers,Generator,我想生成120对中的3位数字 无重复和重复编号 示例:012、013、132有效 01133022202,210无效 注意:012和210是冗余数字,两者都出现,因此无效 /*----Numbers.php----*/ class Numbers{ private $num_set = array();//get 3 digit private $num_basket = array(); //container public $codeNum = "012345678

我想生成120对中的3位数字 无重复和重复编号 示例:
012
、013、132有效 01133022202,
210
无效 注意:
012
210
是冗余数字,两者都出现,因此无效

/*----Numbers.php----*/

class Numbers{
    private $num_set = array();//get 3 digit
    private $num_basket = array(); //container
    public $codeNum = "0123456789";


    public function get_basket(){
        return $this->num_basket;
    }
    public function put_basket($num){
        $this->num_basket[] = $num;
    }

    public function is_exist($num_taken){
        if(in_array($num_taken, $this->num_basket)){
            return true;
        }else{
            return false;
        }        
    }

    public function generate_num(){
        while(count($this->num_set) < 3){
            $get_one_digit = $this->getToken(1);
            if(!in_array($get_one_digit, $this->num_set)){
                $this->num_set[] = $get_one_digit;

            }
        }
        $three_digit = implode($this->num_set);
        $this->num_set = array();
        return $three_digit;
    }

    protected function getToken($length)
    {
        $token = "";

        $max = strlen($this->codeNum); // edited

        for ($i=0; $i < $length; $i++) {
            $token .= $this->codeNum[$this->crypto_rand_secure(0, $max-1)];
        }   
        return $token;
    }

    //generate code
    protected function crypto_rand_secure($min, $max)
    {
        $range = $max - $min;
        if ($range < 1) return $min; // not so random...
        $log = ceil(log($range, 2));
        $bytes = (int) ($log / 8) + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd > $range);
        return $min + $rnd;
    }
}

/*----- index.php ---*/

include("Numbers.php");
$num = New Numbers;

for($i=0;$i<120;$i++){
    $num_item = $num->generate_num();
    while($num->is_exist($num_item) == true){
        $num_item = $num->generate_num();
    }

    $num->put_basket($num_item);
}

$num_basket = $num->get_basket();
if(!empty($num_basket)){
    print "number count: ".count($num_basket)."<br>";
    sort($num_basket);
    foreach($num_basket as $item){
        print $item[0].$item[1].$item[2]." ";
    }

}
我使用的是PHP版本5.6.28 Apache/2.4.23(Win32)OpenSSL/1.0.2h PHP/5.6.28 这是我到目前为止尝试过的,但没有成功

数目:120 027 028 029 036 038 046 069 074 079 093 105 106 109 123 143 145 149 152 162 167 175 182 195 198 204 208 213 216 217 219 235 243 275 287 294 301 302 310 327 341 342 347 352 357 358 365 376 378 380 384 392 402 408 415 423 428 431 453 465 467 468 493 496 509 510 524
573
591597598408658959059291697676467676467707019719719723723743745750527597618198208298408658759059091697676766969670701970984

注意这里的
537
573
无效

/*----Numbers.php----*/

class Numbers{
    private $num_set = array();//get 3 digit
    private $num_basket = array(); //container
    public $codeNum = "0123456789";


    public function get_basket(){
        return $this->num_basket;
    }
    public function put_basket($num){
        $this->num_basket[] = $num;
    }

    public function is_exist($num_taken){
        if(in_array($num_taken, $this->num_basket)){
            return true;
        }else{
            return false;
        }        
    }

    public function generate_num(){
        while(count($this->num_set) < 3){
            $get_one_digit = $this->getToken(1);
            if(!in_array($get_one_digit, $this->num_set)){
                $this->num_set[] = $get_one_digit;

            }
        }
        $three_digit = implode($this->num_set);
        $this->num_set = array();
        return $three_digit;
    }

    protected function getToken($length)
    {
        $token = "";

        $max = strlen($this->codeNum); // edited

        for ($i=0; $i < $length; $i++) {
            $token .= $this->codeNum[$this->crypto_rand_secure(0, $max-1)];
        }   
        return $token;
    }

    //generate code
    protected function crypto_rand_secure($min, $max)
    {
        $range = $max - $min;
        if ($range < 1) return $min; // not so random...
        $log = ceil(log($range, 2));
        $bytes = (int) ($log / 8) + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd > $range);
        return $min + $rnd;
    }
}

/*----- index.php ---*/

include("Numbers.php");
$num = New Numbers;

for($i=0;$i<120;$i++){
    $num_item = $num->generate_num();
    while($num->is_exist($num_item) == true){
        $num_item = $num->generate_num();
    }

    $num->put_basket($num_item);
}

$num_basket = $num->get_basket();
if(!empty($num_basket)){
    print "number count: ".count($num_basket)."<br>";
    sort($num_basket);
    foreach($num_basket as $item){
        print $item[0].$item[1].$item[2]." ";
    }

}
/*--Numbers.php----*/
班级人数{
private$num_set=array();//获取3位数
私有$num_basket=array();//容器
public$codeNum=“0123456789”;
公共职能部门{
返回$this->num_篮子;
}
公共功能放置篮($num){
$this->num_basket[]=$num;
}
公共功能存在($num){
if(在数组中($num\u take,$this->num\u basket)){
返回true;
}否则{
返回false;
}        
}
公共函数generate_num(){
同时(计数($this->num\u set)<3){
$get\u one\u digit=$this->getToken(1);
如果(!在数组中($get\u one\u digit,$this->num\u set)){
$this->num\u set[]=$get\u一位数;
}
}
$three\u digit=内爆($this->num\u set);
$this->num_set=array();
返回$3位数字;
}
受保护函数getToken($length)
{
$token=“”;
$max=strlen($this->codeNum);//已编辑
对于($i=0;$i<$length;$i++){
$token.=$this->codeNum[$this->crypto_rand_secure(0,$max-1)];
}   
返回$token;
}
//生成代码
受保护的函数加密和安全($min,$max)
{
$range=$max-$min;
如果($range<1)返回$min;//不太随机。。。
$log=ceil(log$range,2));
$bytes=(int)($log/8)+1;//字节长度
$bits=(int)$log+1;//以位为单位的长度
$filter=(int)(1$range);
返回$min+$rnd;
}
}
/*-----index.php---*/
包括(“Numbers.php”);
$num=新数字;
对于($i=0;$igenerate_num());
而($num->is\u exist($num\u item)==true){
$num_item=$num->generate_num();
}
$num->put_basket($num_项目);
}
$num_basket=$num->get_basket();
如果(!空($num_basket)){
打印“数字计数:”.count($num_basket)。“
”; 排序($num_basket); foreach($num_篮子作为$item){ 打印$item[0]。$item[1]。$item[2]。“”; } }

代码运行良好,没有显示错误,但没有显示预期的结果。我真的需要帮助。我将非常感谢任何帮助。

我已经重写了代码,因为我认为类和类外的代码组合太多,造成了很大的依赖性(IMHO)

在这段代码中,您创建一个类并说出要生成多少个数字,然后调用
generate()
方法完成所有工作

为了检查以前是否使用过这些数字,我将数字编码到一个位字段并存储它(
encode()
方法只是根据使用的数字添加二进制数)。如果同样的模式再次出现,它只会尝试另一个

class NumberGenerator{
    private $numbersUsed = [];
    private $basket = [];
    private $numbersToGenerate = 0;

    public function __construct( int $numbersToGenerate )   {
        $this->numbersToGenerate = $numbersToGenerate;
    }

    public function generate(){
        $numbers = range(0,9);
        for ( $i = 0; $i < $this->numbersToGenerate; $i++ ) {
            do    {
                shuffle($numbers);
                $number = array_slice($numbers, 0,3);
                $encoded = $this->encode($number);
            }
            while ( in_array($encoded, $this->numbersUsed) );
            $this->basket[] = implode($number);
            $this->numbersUsed[] = $encoded;
        }

        return $this->basket;
    }

    protected  function encode(array $num)  {
        $numbers = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512];
        $sum = 0;
        foreach ( $num as $digit )  {
            $sum += $numbers[$digit];
        }
        return $sum;
    }
}

$generator = new NumberGenerator(120);
print_r($generator->generate());
类号发电机{
私有$numberssused=[];
私人美元篮子=[];
私有$numbersToGenerate=0;
公共函数构造(int$numbersToGenerate){
$this->numbersToGenerate=$numbersToGenerate;
}
公共函数生成(){
$numbers=范围(0,9);
对于($i=0;$i<$this->numbersToGenerate;$i++){
做{
洗牌(数字);
$number=array\u slice($number,0,3);
$encoded=$this->encode($number);
}
而(在数组中($encoded,$this->numberused));
$this->basket[]=内爆($number);
$this->numberssused[]=$encoded;
}
返回$this->basket;
}
受保护的函数编码(数组$num){
$numbers=[1,2,4,8,16,32,64,128,256,512];
$sum=0;
foreach($num作为$digit){
$sum+=$number[$digit];
}
返回$sum;
}
}
$generator=新发电机编号(120);
打印($generator->generate());