[英]How to generate unique number with 3 digits and no double numbers in each digit in PHP
I want to generate 3 digits numbers in 120 pairs No duplication and repeat numbers Example: 012
, 013, 132 is valid 011,333, 022,202, 210
is invalid note: 012
and 210
is redundancy digits both appears therefore it is invalid 我想产生120对没有重复,重复的数字,例如3个号码:
012
,013,132有效011333,022202, 210
无效注: 012
和210
是冗余的数字都出现,因此它是无效的
I am using PHP Version 5.6.28 Apache/2.4.23 (Win32) OpenSSL/1.0.2h PHP/5.6.28 this is what I tried so far but no luck. 我正在使用PHP版本5.6.28 Apache / 2.4.23(Win32)OpenSSL / 1.0.2h PHP / 5.6.28,这是我到目前为止尝试过的,但是没有运气。
number count: 120 027 028 029 036 038 046 069 074 079 093 105 106 109 123 143 145 149 152 153 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 369 376 378 380 384 392 402 408 415 423 428 431 453 465 467 468 490 493 496 506 509 510 512 524 537
541 561 573
591 597 598 609 629 631 634 639 647 689 691 694 697 703 719 723 743 745 750 752 759 761 813 819 820 824 829 840 865 875 890 905 907 912 916 917 921 930 941 945 947 963 965 973 984 数计数:120 027 028 029 036 046 069 074 079 093 105 106 109 123 143 145 149 152 152 153 162 167 175 182 195 198 198 204 208 213 216 217 219 219 235 243 275 287 294 301 301 302 310 327 341 342 347 357 357 358 358 365 369 376 378 380 384 392 402 408 415 423 428 431 453 465 467 468 490 490 493 496 506 509 510 512 524
537
541 541 573
591 597 598 609 629 631 634 639 639 647 689 691 697 697 697 739 743 743 750 750 761 813 819 820 824 829 840 865 875 890 905 907 912 916 917 921 930 941 941 945 947 963 965 973 973 984
Note here 537
and 573
is invalid 请注意,此处的
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]." ";
}
}
the code works fine and display no error but does not display expected result. 该代码可以正常工作,并且不会显示任何错误,但是不会显示预期的结果。 I really need help.
我真的需要帮助 I will greatly appreciate any help.
我将不胜感激任何帮助。
I've rewritten the code as I think there is too much combination of the class and the code outside the class which creates to much of a dependency (IMHO). 我重写了代码,因为我认为类和类外部的代码组合过多,从而造成了很大的依赖关系(IMHO)。
In this code, you create a class and say how many numbers you want to generate, then calling the generate()
method does all of the work for you. 在此代码中,您将创建一个类并说出要生成的数字,然后调用
generate()
方法为您完成所有工作。
To check if the numbers have been used before, I encode the number to a bit field and store this (the encode()
method just adds binary numbers according to the digits used). 要检查以前是否使用过数字,我将数字编码到位字段中并存储了该字段(
encode()
方法只是根据使用的数字添加二进制数字)。 If this same pattern happens again, it just tries another one. 如果相同的模式再次发生,它将尝试另一个。
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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.