yakoffka.ru
    грабли, костыли и велосипеды php, css, html, js и прочего

    Функция на php для получения уникального рандомного префикса

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

    Для реализации задуманного я воспользовался встроенными функциями bin2hex(), random_bytes() и pow().

    PHP Code:
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

      $ap
    =array(); // массив для хранения использованных значений
      
    $l=1// количество разрядов префикса/постфикса

      // проверочный цикл
      
    for($i=0;$i<300;$i++){

        while(
    in_array(($p=bin2hex(random_bytes($l))),$ap)){
          if(
    count($ap)>=pow(16,$l+1)){
            echo 
    "<br>\nИспользованы все возможные варианты.
              Необходимо повысить разрядность!
              count(\$ap)="
    .(count($ap)-1)."; \$l='$l';<br>\n";
            
    $l++;
          }
        }

        
    $ap[]=$p;
        echo 
    "\$p='$p'; ";// префикс/постфикс

      
    }


      unset(
    $p,$ap,$l,$i);
      
    Result:
    $p='c3'; $p='a5'; $p='84'; $p='fa'; $p='46'; $p='00'; $p='29'; $p='51'; $p='07'; $p='ad'; $p='2c'; $p='ff'; $p='c5'; $p='42'; $p='31'; $p='02'; $p='ea'; $p='5b'; $p='66'; $p='1b'; $p='b3'; $p='cf'; $p='43'; $p='13'; $p='77'; $p='80'; $p='e7'; $p='d5'; $p='b9'; $p='3e'; $p='a8'; $p='14'; $p='8f'; $p='2b'; $p='57'; $p='53'; $p='44'; $p='8b'; $p='6d'; $p='56'; $p='d0'; $p='f2'; $p='6b'; $p='86'; $p='ec'; $p='9b'; $p='ee'; $p='5e'; $p='db'; $p='af'; $p='25'; $p='5d'; $p='98'; $p='a3'; $p='94'; $p='e5'; $p='09'; $p='dc'; $p='d1'; $p='58'; $p='a6'; $p='f6'; $p='49'; $p='74'; $p='f8'; $p='9a'; $p='85'; $p='b1'; $p='8c'; $p='3c'; $p='76'; $p='1c'; $p='0c'; $p='67'; $p='8e'; $p='fe'; $p='2e'; $p='24'; $p='3d'; $p='95'; $p='3b'; $p='55'; $p='cc'; $p='fb'; $p='6c'; $p='97'; $p='93'; $p='03'; $p='6a'; $p='cd'; $p='47'; $p='f3'; $p='a4'; $p='27'; $p='5f'; $p='28'; $p='0e'; $p='ac'; $p='7d'; $p='a1'; $p='e0'; $p='b4'; $p='5c'; $p='e2'; $p='17'; $p='1e'; $p='68'; $p='0d'; $p='a0'; $p='b7'; $p='7e'; $p='01'; $p='88'; $p='3f'; $p='2f'; $p='87'; $p='d6'; $p='06'; $p='11'; $p='ef'; $p='c4'; $p='39'; $p='da'; $p='bc'; $p='c8'; $p='a9'; $p='79'; $p='f7'; $p='6f'; $p='f1'; $p='c1'; $p='08'; $p='70'; $p='9f'; $p='7f'; $p='8a'; $p='9e'; $p='18'; $p='be'; $p='37'; $p='ae'; $p='0f'; $p='f4'; $p='71'; $p='81'; $p='96'; $p='41'; $p='75'; $p='9d'; $p='65'; $p='99'; $p='b6'; $p='73'; $p='e8'; $p='20'; $p='69'; $p='05'; $p='26'; $p='d9'; $p='59'; $p='21'; $p='61'; $p='4b'; $p='54'; $p='50'; $p='ab'; $p='2d'; $p='c2'; $p='30'; $p='12'; $p='82'; $p='cb'; $p='4e'; $p='15'; $p='2a'; $p='1a'; $p='d8'; $p='f9'; $p='eb'; $p='22'; $p='45'; $p='52'; $p='c6'; $p='32'; $p='34'; $p='38'; $p='b0'; $p='dd'; $p='f0'; $p='b5'; $p='b8'; $p='64'; $p='d2'; $p='b2'; $p='ed'; $p='10'; $p='f5'; $p='a7'; $p='16'; $p='df'; $p='6e'; $p='4c'; $p='23'; $p='4a'; $p='a2'; $p='90'; $p='ce'; $p='7a'; $p='d7'; $p='0b'; $p='89'; $p='7c'; $p='fc'; $p='83'; $p='62'; $p='ba'; $p='fd'; $p='36'; $p='8d'; $p='91'; $p='4d'; $p='35'; $p='04'; $p='19'; $p='e3'; $p='4f'; $p='78'; $p='de'; $p='c0'; $p='9c'; $p='7b'; $p='40'; $p='c7'; $p='48'; $p='0a'; $p='e1'; $p='63'; $p='e4'; $p='72'; $p='d4'; $p='e9'; $p='1d'; $p='aa'; $p='d3'; $p='3a'; $p='1f'; $p='60'; $p='bf'; $p='5a'; $p='e6'; $p='c9'; $p='bb'; $p='bd'; $p='33'; $p='92'; $p='ca';
    Использованы все возможные варианты. Необходимо повысить разрядность! count($ap)=255; $l='1';
    $p='16b4'; $p='8f90'; $p='9590'; $p='f0ec'; $p='d1fc'; $p='f7fc'; $p='7e1b'; $p='b6c0'; $p='2ce8'; $p='fb4f'; $p='40db'; $p='9864'; $p='3548'; $p='ef72'; $p='6e5c'; $p='dcd9'; $p='005e'; $p='685c'; $p='e14d'; $p='1a5b'; $p='6de6'; $p='9c71'; $p='f23c'; $p='18b4'; $p='f636'; $p='089e'; $p='81c8'; $p='4e2b'; $p='68f6'; $p='39be'; $p='588b'; $p='42ea'; $p='65dd'; $p='2dac'; $p='a6cd'; $p='ce1c'; $p='4347'; $p='7c76'; $p='5a9c'; $p='662b'; $p='d9ab'; $p='2a49'; $p='e6a3'; $p='a16f';

    Для получения действительно максимального количества префиксов наименьшей возможной длины при $l>2 ($l - количество разрядов шестнадцатиричного числа) необходимо заставить прекратить перебирать варианты при количестве элементов массива $ap равном сумме всех возможных результатов со всеми значениями $l, но я решил пренебречь этим в целях сокращения кода.

    Однострочная запись:

    PHP Code:
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

      $ap
    =array();$l=1// указывается в начале скрипта

      // вызывается по мере необходимости в следующем уникальном постфиксе
      
    while(in_array(($p=bin2hex(random_bytes($l))),$ap)){if(count($ap)>=pow(16,$l+1)){$l++;}}$ap[]=$p;
      echo 
    "name_$p<br>\n";

      
    // повторное использование постфикса
      
    echo "повторное использование постфикса name_$p<br>\n";

      while(
    in_array(($p=bin2hex(random_bytes($l))),$ap)){if(count($ap)>(pow(16,$l+1)-1)){$l++;}}$ap[]=$p;
      echo 
    "name_$p<br>\n";

      while(
    in_array(($p=bin2hex(random_bytes($l))),$ap)){if(count($ap)>(pow(16,$l+1)-1)){$l++;}}$ap[]=$p;
      echo 
    "name_$p<br>\n";

      while(
    in_array(($p=bin2hex(random_bytes($l))),$ap)){if(count($ap)>(pow(16,$l+1)-1)){$l++;}}$ap[]=$p;
      echo 
    "name_$p<br>\n";


      
    // удаляем отработавшие переменные
      
    unset($p,$ap,$l);
      
    Result:
    name_7f
    повторное использование постфикса name_7f
    name_dd
    name_d8
    name_89

    Запись в виде функции:

    PHP Code:
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

      
    // функция для получения уникального рандомного префикса
      
    function ru_prefix_34(array $ap){
        
    $l=1;
        while(
    in_array(($p=bin2hex(random_bytes($l))),$ap)){if(count($ap)>=pow(16,$l+1)){$l++;}}$ap[]=$p;
        return 
    $ap;
      }
      
    // /функция для получения уникального рандомного префикса

      
    $ap=array(); // объявление массива для хранения использованных значений


      // ...

      // вызывается по мере необходимости в следующем уникальном постфиксе
      
    echo "name_".end($ap=ru_prefix_34($ap))."<br>\n"// однострочный вызов функции

      // вызывается по мере необходимости в следующем уникальном постфиксе
      
    echo "name_".end($ap=ru_prefix_34($ap))."<br>\n"// однострочный вызов функции

      // для возможности повторного использования постфикса сначала кладём его в переменную,
      
    $p=end($ap=ru_prefix_34($ap));
      
    // а затем подставляем значение
      
    echo "name_$p<br>\n";
      
    // повторное использование постфикса
      
    echo "повторное использование постфикса name_$p<br>\n";

      
    // вызывается по мере необходимости в следующем уникальном постфиксе
      
    echo "name_".end($ap=ru_prefix_34($ap))."<br>\n"// однострочный вызов функции


      // ...


      // удаляем отработавшие переменные
      
    unset($p,$ap);
      
    Result:
    name_12
    name_18
    name_83
    повторное использование постфикса name_83
    name_5e

    Для проверки работы функции получим максимально возможное число двухразрядных префиксов ($l=1), сложим полученные значения в массив '$arr', отсортируем его и выведем пары ключ/значение, представив ключ в виде шестнадцатиричного числа. Таким образом пропуски либо повторения будет легко отследить:

    проверка работы функции:
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

      
    // функция для получения уникального рандомного префикса
      
    function ru_prefix_ee(array $ap){
        
    $l=1;
        while(
    in_array(($p=bin2hex(random_bytes($l))),$ap)){if(count($ap)>=pow(16,$l+1)){$l++;}}$ap[]=$p;
        return 
    $ap;
      }
      
    // /функция для получения уникального рандомного префикса
      
    $ap=array(); // объявление массива для хранения использованных значений


      // проверочный цикл
      
    for($i=0;$i<256;$i++){
        
    //$ap=ru_prefix_ee($ap);
        
    $p=end($ap=ru_prefix_ee($ap)); // однострочный вызов функции
        
    $arr[]=$p;
      }

      
    sort($arr);
      foreach(
    $arr as $k=>$p){
        echo 
    "$p <-> ".dechex($k).";<br>";
      }unset(
    $arr);


      
    // удаляем отработавшие переменные
      
    unset($p,$ap,$k);
      
    Result:
    00 <-> 0;
    01 <-> 1;
    02 <-> 2;
    03 <-> 3;
    04 <-> 4;
    05 <-> 5;
    06 <-> 6;
    07 <-> 7;
    08 <-> 8;
    09 <-> 9;
    0a <-> a;
    0b <-> b;
    0c <-> c;
    0d <-> d;
    0e <-> e;
    0f <-> f;
    10 <-> 10;
    11 <-> 11;
    12 <-> 12;
    13 <-> 13;
    14 <-> 14;
    15 <-> 15;
    16 <-> 16;
    17 <-> 17;
    18 <-> 18;
    19 <-> 19;
    1a <-> 1a;
    1b <-> 1b;
    1c <-> 1c;
    1d <-> 1d;
    1e <-> 1e;
    1f <-> 1f;
    20 <-> 20;
    21 <-> 21;
    22 <-> 22;
    23 <-> 23;
    24 <-> 24;
    25 <-> 25;
    26 <-> 26;
    27 <-> 27;
    28 <-> 28;
    29 <-> 29;
    2a <-> 2a;
    2b <-> 2b;
    2c <-> 2c;
    2d <-> 2d;
    2e <-> 2e;
    2f <-> 2f;
    30 <-> 30;
    31 <-> 31;
    32 <-> 32;
    33 <-> 33;
    34 <-> 34;
    35 <-> 35;
    36 <-> 36;
    37 <-> 37;
    38 <-> 38;
    39 <-> 39;
    3a <-> 3a;
    3b <-> 3b;
    3c <-> 3c;
    3d <-> 3d;
    3e <-> 3e;
    3f <-> 3f;
    40 <-> 40;
    41 <-> 41;
    42 <-> 42;
    43 <-> 43;
    44 <-> 44;
    45 <-> 45;
    46 <-> 46;
    47 <-> 47;
    48 <-> 48;
    49 <-> 49;
    4a <-> 4a;
    4b <-> 4b;
    4c <-> 4c;
    4d <-> 4d;
    4e <-> 4e;
    4f <-> 4f;
    50 <-> 50;
    51 <-> 51;
    52 <-> 52;
    53 <-> 53;
    54 <-> 54;
    55 <-> 55;
    56 <-> 56;
    57 <-> 57;
    58 <-> 58;
    59 <-> 59;
    5a <-> 5a;
    5b <-> 5b;
    5c <-> 5c;
    5d <-> 5d;
    5e <-> 5e;
    5f <-> 5f;
    60 <-> 60;
    61 <-> 61;
    62 <-> 62;
    63 <-> 63;
    64 <-> 64;
    65 <-> 65;
    66 <-> 66;
    67 <-> 67;
    68 <-> 68;
    69 <-> 69;
    6a <-> 6a;
    6b <-> 6b;
    6c <-> 6c;
    6d <-> 6d;
    6e <-> 6e;
    6f <-> 6f;
    70 <-> 70;
    71 <-> 71;
    72 <-> 72;
    73 <-> 73;
    74 <-> 74;
    75 <-> 75;
    76 <-> 76;
    77 <-> 77;
    78 <-> 78;
    79 <-> 79;
    7a <-> 7a;
    7b <-> 7b;
    7c <-> 7c;
    7d <-> 7d;
    7e <-> 7e;
    7f <-> 7f;
    80 <-> 80;
    81 <-> 81;
    82 <-> 82;
    83 <-> 83;
    84 <-> 84;
    85 <-> 85;
    86 <-> 86;
    87 <-> 87;
    88 <-> 88;
    89 <-> 89;
    8a <-> 8a;
    8b <-> 8b;
    8c <-> 8c;
    8d <-> 8d;
    8e <-> 8e;
    8f <-> 8f;
    90 <-> 90;
    91 <-> 91;
    92 <-> 92;
    93 <-> 93;
    94 <-> 94;
    95 <-> 95;
    96 <-> 96;
    97 <-> 97;
    98 <-> 98;
    99 <-> 99;
    9a <-> 9a;
    9b <-> 9b;
    9c <-> 9c;
    9d <-> 9d;
    9e <-> 9e;
    9f <-> 9f;
    a0 <-> a0;
    a1 <-> a1;
    a2 <-> a2;
    a3 <-> a3;
    a4 <-> a4;
    a5 <-> a5;
    a6 <-> a6;
    a7 <-> a7;
    a8 <-> a8;
    a9 <-> a9;
    aa <-> aa;
    ab <-> ab;
    ac <-> ac;
    ad <-> ad;
    ae <-> ae;
    af <-> af;
    b0 <-> b0;
    b1 <-> b1;
    b2 <-> b2;
    b3 <-> b3;
    b4 <-> b4;
    b5 <-> b5;
    b6 <-> b6;
    b7 <-> b7;
    b8 <-> b8;
    b9 <-> b9;
    ba <-> ba;
    bb <-> bb;
    bc <-> bc;
    bd <-> bd;
    be <-> be;
    bf <-> bf;
    c0 <-> c0;
    c1 <-> c1;
    c2 <-> c2;
    c3 <-> c3;
    c4 <-> c4;
    c5 <-> c5;
    c6 <-> c6;
    c7 <-> c7;
    c8 <-> c8;
    c9 <-> c9;
    ca <-> ca;
    cb <-> cb;
    cc <-> cc;
    cd <-> cd;
    ce <-> ce;
    cf <-> cf;
    d0 <-> d0;
    d1 <-> d1;
    d2 <-> d2;
    d3 <-> d3;
    d4 <-> d4;
    d5 <-> d5;
    d6 <-> d6;
    d7 <-> d7;
    d8 <-> d8;
    d9 <-> d9;
    da <-> da;
    db <-> db;
    dc <-> dc;
    dd <-> dd;
    de <-> de;
    df <-> df;
    e0 <-> e0;
    e1 <-> e1;
    e2 <-> e2;
    e3 <-> e3;
    e4 <-> e4;
    e5 <-> e5;
    e6 <-> e6;
    e7 <-> e7;
    e8 <-> e8;
    e9 <-> e9;
    ea <-> ea;
    eb <-> eb;
    ec <-> ec;
    ed <-> ed;
    ee <-> ee;
    ef <-> ef;
    f0 <-> f0;
    f1 <-> f1;
    f2 <-> f2;
    f3 <-> f3;
    f4 <-> f4;
    f5 <-> f5;
    f6 <-> f6;
    f7 <-> f7;
    f8 <-> f8;
    f9 <-> f9;
    fa <-> fa;
    fb <-> fb;
    fc <-> fc;
    fd <-> fd;
    fe <-> fe;
    ff <-> ff;