Цикл, который проверяет, существует ли он в таблице и генерирует ли случайную строку - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть функция, которая генерирует случайную строку

    $found = true;
function generateRandomString($length = 10) {
$str = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
 while($found == true)
{
     $check1 = $baza->query("SELECT key_X FROM generatedkey WHERE generatekey = '$str'");;
    if(mysql_num_rows($check1)==0) {
        $found = false;
    } else {

       $str = generateRandomString();

    }
}
return $str;
$found = true;
}

Я хотел бы знать, правильно ли это, потому что я не знаю, как это проверить. Эта функция должна работать так:

  • генерирует случайную строку
  • проверить, существует ли строка в таблице
  • если существует (> создать новый)
  • если не существует

  • возврат случайной строки

1 Ответ

0 голосов
/ 01 апреля 2019

Есть несколько проблем с вашим кодом:

$found = true; //defined outside the function

function generateRandomString($length = 10) {
     //string is generated outside the loop
    $str = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);

    while($found == true) //found is undefined so this never runs
    {
         $check1 = $baza->query("SELECT key_X FROM generatedkey WHERE generatekey = '$str'");;
        if(mysql_num_rows($check1)==0) {
            $found = false;
        } else {
           $str = generateRandomString(); //recursion or a loop not both
        }
    }
    return $str;
    $found = true; //pointless
}

С циклом

function generateRandomString($length = 10) {
    while(true)
    {
        $str = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
        $check1 = $baza->query("SELECT key_X FROM generatedkey WHERE generatekey = '$str'");


        if(mysql_num_rows($check1)==0) break; //no results=unique, so bail out of the loop
    }
    return $str;
}

С рекурсией

function generateRandomString($length = 10) {

    $str = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
    $check1 = $baza->query("SELECT key_X FROM generatedkey WHERE generatekey = '$str'");
    if(mysql_num_rows($check1)!=0) $str=generateRandomString($length); //results=not unique, do recursion

    return $str;
}

PS.Я оставлю подготовленный оператор здесь, так как это просто случайная строка, без ввода пользователя.

Лично

Я думаю, что использование цикла хорошо для этого,Единственное, что я хотел бы добавить, - это вызвать исключение, если оно выполняет слишком много итераций.Это только один из них, это никогда не должно произойти.

Одна вещь, которую нужно учитывать, это 10 на самом деле не так уж долго.У нас недавно было около 2% отказов в кодах сертификатов (8 длинных).Единственное, что я могу придумать, - это неуникальные коллизии (это сторонняя LMS).Этой системе около 6 лет, и я работаю над ее заменой.Поэтому в зависимости от частоты, которую вы генерируете, они не бесконечны, и со временем вероятность столкновения возрастает.

function generateRandomString($length = 10, $max_iterations=100) {
    for($i=0;$i<$max_iterations;++$i){
        $str = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
        $check1 = $baza->query("SELECT key_X FROM generatedkey WHERE generatekey = '$str'");

        if(mysql_num_rows($check1)==0) return $str; //return when condition met
    }
    //if were here then we didn't return $str above
    throw new Exception("too many iterations");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...