генерация уникального идентификатора длиной в 6 символов, используя только a-z A-Z 0-9

#php #math #logic

#php #математика #Логические

Вопрос:

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

 $string             = 'aaaaaa';

function hp_update_uid($string)
{
    $position           = strpos($string, '9');



    if($position === 0)
    {
        return FALSE;
    }
    elseif($position === FALSE)
    {
        $position   = -1;
    }
    else
    {
        $position   = -(7-$position);
    }

    #var_dump($position);
    #exit;

    $character_ord      = ord(substr($string, $position, 1));

    if($character_ord == 122)
    {
        $character_ord  = 65;
    }
    elseif($character_ord == 90)
    {
        $character_ord = 48;
    }
    else
    {
          $character_ord;
    }

    $string             = substr_replace($string, chr($character_ord), $position, 1);

    return $string;
}

for($i = 0; $i < 1000; $i  )
{
    $string = hp_update_uid($string);
    echo $string . '<br />';
}
  

Это приведет к следующему результату: https://gist.github.com/937b148a126924b9429d

Как мне действительно сгенерировать уникальный идентификатор длиной в 6 символов, используя только a-z A-Z 0-9 и используя логическое увеличение?

Комментарии:

1. что вы подразумеваете под логическим увеличением?

2. вы имеете в виду, что вам нужны не только aaaaaa, aaaaaab, aaaaac и так далее, но и aaaabaa?

3. @Sascha Galley, точно.

Ответ №1:

Как мне действительно сгенерировать уникальный идентификатор длиной в 6 символов, используя только a-z A-Z 0-9 и используя логическое увеличение?

Если их необходимо увеличить с шагом в 1, начните с 0, затем увеличьте на 1 и преобразуйте полученное число в base62 (26 из [A-Z] 26 из [a-z] 10 из [0-9]).

Остановитесь, когда длина больше не подходит ( 62^6 - 1 если я не ошибаюсь).

Комментарии:

1. Ок, не уверен, что я понял. Можете ли вы проиллюстрировать это примером?

2. Возьмите обычное целое число, каждый раз увеличивая его на 1. Затем преобразуйте в base62 (т. Е. аналогично преобразованию в шестнадцатеричный код, но с [0-9a-zA-Z] алфавитом вместо [0-9a-f] ). 0 есть 0 , 1 есть 1 , … 10 есть a , 11 есть b , … 61 есть Z , 62 есть 10 , …, 63 есть 11 , … до 72 которого есть 1a . ………………………………, 62^6 - 1 есть ZZZZZZ .

3. Смотрите здесь некоторый PHP-код преобразования base 62: php.net/manual/en/function.base-convert.php#52450

4. Таким образом, это должно привести к ZZZZZZ gist.github.com/fd4ff7c479771251df82 хотя он генерирует X. Нет, подождите, похоже, PHP не понял 62 ^ 6 как при вводе. Это работает нормально. Спасибо.

5. @Guy: разве ^ не является оператором XOR (или каким-либо другим двоичным оператором) в PHP? 🙂

Ответ №2:

Вы можете использовать эту функцию:

 function Base($number, $input, $output, $charset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
    if (strlen($charset) >= 2)
    {
        $input = max(2, min(intval($input), strlen($charset)));
        $output = max(2, min(intval($output), strlen($charset)));
        $number = ltrim(preg_replace('~[^' . preg_quote(substr($charset, 0, max($input, $output)), '~') . '] ~', '', $number), $charset[0]);

        if (strlen($number) > 0)
        {
            if ($input != 10)
            {
                $result = 0;

                foreach (str_split(strrev($number)) as $key => $value)
                {
                    $result  = pow($input, $key) * intval(strpos($charset, $value));
                }

                $number = $result;
            }

            if ($output != 10)
            {
                $result = $charset[$number % $output];

                while (($number = intval($number / $output)) > 0)
                {
                    $result = $charset[$number % $output] . $result;
                }

                $number = $result;
            }

            return $number;
        }

        return $charset[0];
    }

    return false;
}
  

Пример использования (@ IDEOne.com ):

 $i = -1;
$string = '';
$charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

while (strlen($string) <= 6)
{
    echo $string = str_pad(Base(  $i, 10, 62, $charset), 6, 'a', STR_PAD_LEFT);
}