2015-09-25 4 views
0

Я хотел бы использовать php uniqid() в шаблоне smarty для моей небольшой системы бронирования (для продукта), чтобы генерировать значение UNIQUE, которое будет делать для номера резервирования. По умолчанию uniqid() слишком длинный для моей цели, как я могу сделать это как 5-6 символов?Как сделать uniqid короче

+0

Как бы вы представить себе генерирует уникальный идентификатор только 6 символов? Это скоро закончится плохой – PeeHaa

+0

Вы можете использовать генератор строк, подобный тому, что упоминается [здесь] (http://stackoverflow.com/questions/4356289/php-random-string-generator), но ему нужно будет запросить его уникальность раньше будучи в состоянии безопасно использовать его. Кроме того, чем короче строка и чем меньше пул символов, тем скорее вы начнете сталкиваться с проблемами. – user2959229

+0

@PeeHaa: Даже если вы используете только цифры и прописные буквы и удаляете все неоднозначные символы - мой предпочтительный алфавит для таких вещей - '3479ACEFHJKLMNPRTUVWXY' есть 22^10 = 26559922791424 разных идентификаторов. Достаточно достаточно для многих вещей. – VolkerK

ответ

0

предварительный ответ:

<?php 
function toBase(/* positiv integer*/ $n, array $alphabet) { 
    $retval = ''; 
    do { 
     $retval .= $alphabet[ $n%count($alphabet) ]; 
     $n = intval($n/count($alphabet)); 
    } 
    while(($n=intval($n)) > 0); 
    return $retval; 
} 

function getCode() { 
    static $alphabet = null; 
    if($alphabet==null) { 
     $alphabet = str_split('3479ACEFHJKLMNPRTUVWXY'); 
    } 

    // get a random number 
    // and "encode" it using the alphabet 
    $code = toBase(mt_rand(), $alphabet); 
    // this might be both 
    // - too long 
    // - and too short* 
    // so first get the last 6 characters (if there are that much) 
    $code = substr($code, -6); 
    // and if there wasn't, pad them with 'zeros' (according to the alphabet that's a '3') 
    $code = str_pad($code, 6, $alphabet[0]); 

    return $code; 

    // *) the "too short" part could be avoided via mt_rand(22^6, ...) 
    // but I want to keep it in the range of a 32bit signed integer 
} 

Получить код() дает коды, как

YFTRXA 
MRMTMV 
YC9HVN 
VWCAUE 
JEVXUF 
WWMEYU 
KLWAML 
YCKE3V 
37KJ3P 
ME9EKU 

Я опробованный() Получить код (один раз) через

function testCodes() { 
    $codes = []; 
    for($i=0; $i<2000; $i++) { 
     $codes[] = getCode(); 
    } 
    $withoutCollisions = array_unique($codes); 
    return count($codes)-count($withoutCollisions); 
} 


$collisions = []; 
for($i=0; $i<5000; $i++) { 
    $c = testCodes(); 
    if (!isset($collisions[$c])) { 
     $collisions[$c] = 0; 
    } 
    $collisions[$c] += 1; 
} 

var_dump($collisions); 

и выход был

array(3) { 
    [0]=> 
    int(4899) 
    [1]=> 
    int(100) 
    [2]=> 
    int(1) 
} 

Итак, есть столкновения (набор из 2000 кодов с одним или двумя дублетами), но я бы сказал, за то, что вы, по-видимому, пытаетесь достичь, это в парке с мячом. Коэффициент столкновений достаточно мал, чтобы вы могли даже помещать уникальное противопоставление в базу данных в этом поле и просто повторить попытку на столкновении.

.... НО не стесняйтесь, чтобы получить к https://security.stackexchange.com/ и есть этот алгоритм лоскуток на куски ;-)

+0

Спасибо VolkerK. Я провешу его в понедельник и дам вам знать. Хороших выходных! – Caipiranha

+0

Но не играйте с длиной и алфавитом ;-) Они «жестко закодированы» в getCode() по какой-либо причине; это не общий ответ. В 32-битном значении целого диапазона значений мало места для маневра. И добавление '' '' '' '' '' '' '' '' '' '' '' '' если меньше 6 символов, безусловно, создает смещение по отношению к этой цифре. Но, в любом случае, я считаю, что этого достаточно для вашей цели, и это довольно просто. – VolkerK

+0

Я не использовал ваше решение, потому что я не понимаю его, но то, что я сделал, это использовать substr uniqid только для 6 символов, но я до сих пор не знаю, как передать переменную, добавили этот UNIQUE ID в smarty .tpl файл :(Мне нужно передать его, потому что он используется в подтверждении по электронной почте в США и в CUSTOMER, которые представляют собой 2 разных файла .tpl. – Caipiranha

Смежные вопросы