PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

unpack> <time_sleep_until
Last updated: Fri, 04 Jul 2008

view this page in

uniqid

(PHP 4, PHP 5)

uniqid — Generar un ID único

Descripción

string uniqid ([ string $prefijo [, bool $mas_entropia ]] )

Obtiene un identificador con prefijo único basado en la hora actual en microsegundos.

Lista de parámetros

prefijo

Puede resultar útil, por ejemplo, si se generan identificadores simultáneamente en varias máquinas que pueden estar generando el identificador en el mismo microsegundo.

Con un prefijo vacío, la cadena devuelta tendrá una longitud de 13 caracteres. Si mas_entropia es TRUE, tendrá 23 caracteres.

mas_entropia

Si es TRUE, uniqid() agregará entropía adicional (usando el generador de congruencia lineal combinado) al final del valor de retorno, lo cual puede hacer más únicos los resultados.

Valores retornados

Devuelve el identificador único, como una cadena.

Ejemplos

Si necesita un identificador o lexema único e intenta entregar ese valor al usuario a través de la red (mediante cookies de sesión), es recomendable que use algo como lo siguiente:

Esto creará un identificador de 32 caracteres (un número hexadecimal de 128 bits) que es extremadamente difícil de predecir.

Example #1 Ejemplo de uniqid()

<?php
// sin prefijo
// funciona únicamente en PHP 5 y versiones posteriores
$token md5(uniqid());

// mejor, difícil de adivinar
$mejor_token md5(uniqid(rand(), true));
?>

Registro de cambios

Versión Descripción
5.0.0 El parámetro prefijo se hizo opcional.
4.3.1 El límite de 114 caracteres de longitud para prefijo fue elevado.



unpack> <time_sleep_until
Last updated: Fri, 04 Jul 2008
 
add a note add a note User Contributed Notes
uniqid
mark at whytewaters dot com
26-Feb-2008 03:39
If you want many ids and performance of this function is an issue why not pull uniquid() out of the loop, eg:

$base = uniqueid();
$ids[] = array();

for ($index = 0; $index < 100000; $index++) 
    $ids[] = $base . '.' . $index;
nodkz at mail dot ru
15-Jan-2008 11:00
I use such UUID (it not RFC!!!)
(server_id)-(clientIP)-(unixtime)-(milliseconds)-(random)

 I can easyly determine which server at which time and who initiate creating of object.

<?php

$u
=uuid();   // 0001-7f000001-478c8000-4801-47242987
echo $u;
echo
"<br>";
print_r(uuidDecode($u)); // Array ( [serverID] => 0001 [ip] => 127.0.0.1 [unixtime] => 1200390144 [micro] => 0.28126525878906 )

function uuid($serverID=1)
{
   
$t=explode(" ",microtime());
    return
sprintf( '%04x-%08s-%08s-%04s-%04x%04x',
       
$serverID,
       
clientIPToHex(),
       
substr("00000000".dechex($t[1]),-8),   // get 8HEX of unixtime
       
substr("0000".dechex(round($t[0]*65536)),-4), // get 4HEX of microtime
       
mt_rand(0,0xffff), mt_rand(0,0xffff));
}

function
uuidDecode($uuid) {
   
$rez=Array();
   
$u=explode("-",$uuid);
    if(
is_array($u)&&count($u)==5) {
       
$rez=Array(
           
'serverID'=>$u[0],
           
'ip'=>clientIPFromHex($u[1]),
           
'unixtime'=>hexdec($u[2]),
           
'micro'=>(hexdec($u[3])/65536)
        );
    }
    return
$rez;
}

function
clientIPToHex($ip="") {
   
$hex="";
    if(
$ip=="") $ip=getEnv("REMOTE_ADDR");
   
$part=explode('.', $ip);
    for (
$i=0; $i<=count($part)-1; $i++) {
       
$hex.=substr("0".dechex($part[$i]),-2);
    }
    return
$hex;
}

function
clientIPFromHex($hex) {
   
$ip="";
    if(
strlen($hex)==8) {
       
$ip.=hexdec(substr($hex,0,2)).".";
       
$ip.=hexdec(substr($hex,2,2)).".";
       
$ip.=hexdec(substr($hex,4,2)).".";
       
$ip.=hexdec(substr($hex,6,2));
    }
    return
$ip;
}

?>
smp_info at yahoo dot com
06-Sep-2007 02:38
This function is painfully slow if you're using it to give images random names inside of a loop.  The following function will give you a random name *every* time and is much faster.

<?php

function nameImage($imgExtension)
{
    return
time() . substr(md5(microtime()), 0, rand(5, 12)) . $imgExtension;
}

?>
dot dot dot dot dot alexander at gmail dot com
13-Jun-2007 11:28
I use this mangle currently:
( inserts the IP, uses time() and a prefix, aside the uniqid)

<?php
if(!function_exists("newid")){

    function
newid($prefix = "user_"){
        return (
$prefix . uniqid( hash("md5", time()), TRUE ) . time() . @$_SERVER['REMOTE_ADDR']);
    }
/* endfunction */

}/* endif  */
?>
ken at smallboxsoftware
17-May-2007 06:34
Just to note this function is fairly slow, and can bring your script to a crawl if it is in a loop. Strangely if you run it as uniqid('', true) it runs much more quickly
rjchallen at gmail dot com
17-May-2007 05:08
If you can guarantee a connection to mysql when you need your UUID then you can wrap up MySQL's (v5+) function.

function uuid() {
    return mysql_result(mysql_query('Select UUID()'),0);
}
kristoffer dot paro at gmail dot com
13-May-2007 05:05
In response to the notes about UUID generation added by mimec and lance_rushing at hotmail dot com.

Calling mt_rand the fewest possible times is not necessarily the fastest, if it heavily utilizes string handling routines. I did a quick benchmark between the two functions and discovered that lance's function (using only 5 mt_rands) was about 6.5 times _slower_ than mimec's on my system.
Jason
27-Mar-2007 10:10
Neither the pseudo-random number rand() nor the Mersenne Twister algorithms are cryptographically strong, and this is well known.  Simply combining non-cryptographically strong algorithms doesn't not make a cryptographically strong algorithm either.  Mersenne Twister is a fast algorithm with good k-distribution which will give you numbers for a long time before it repeats itself.  MT, rand(), and MD5 should NOT be used for encryption, or for cookies that that store a session ID that gives personal information.  A simple application where non-collision of session IDs is highly preferred but not critical, such as storing a user's shopping cart items for when they return to your site (but not their personal information), IS a good use for the MT, rand() MD5, uniqid() and combinations thereof.
mailrinke at _cutthis_yahoo dot com
19-Feb-2007 02:06
I have been using mimecs version lately and do not think it's safe to think the results are always unqiue.

Although it could be just my bad programming, I found exactly 1 collission while debugging my code. It seems to me that if my code was incorrect it would have happened more than once.

I recommend anyone to include time as a factor of such an ID as to be a little more certain it is in fact unique.
Emery
31-Jan-2007 09:13
The example given in this document for a "better token" should be:

<?php
$better_token
= uniqid(md5(rand()), true);
?>

As it is now, the result isn't guaranteed to be unique, because MD5 has collisions.
lance_rushing at hotmail dot com
23-Jan-2007 09:43
wooshoofoo, the reason mimec is calling mt_rand multiple times is because the largest number mt_rand can produce is 2^31 (2147483647, as reported by mt_getrandmax() on my server).  RFC 4122 requires a 128 bit value.

Also they are not "4 digit sequeces", but 4 digit hexadecimal numbers.  16^4 == 2^16.

mimec's limiting each random result to 2^16 avoids problem of PHP's 2^32 integer max (http://php.net/manual/en/language.types.integer.php).

If you want to call mt_rand fewer times:  mimec's version calls mt_rand 8 times ( 16 bits * 8 = 128 bits ).  You *could* call mt_rand 5 times ( 31 bits + 31 bits + 31 bits + 31 bits + 4 bits = 128 bits ).  But then you would have keep all your values as strings.

Something like:

<?php
/**
 * Another (ugly) "random or pseudo-random" version of RFC 4122
 *
 * This version calls mt_rand() the fewest possible times.
 * if mt_getrandmax() == 2^31 then this will call mt_rand() 5 times YMMV
 *
 * Personally, I would use mimec's version
 * To handle the large values, we'll keep everything as strings.
 *
 * @return string
 */
function uuid() {   

    
// Generate 128 bit random sequence
    
$randmax_bits = strlen(base_convert(mt_getrandmax(), 10, 2));  // how many bits is mt_getrandmax()
    
$x = '';
     while (
strlen($x) < 128) {
        
$maxbits = (128 - strlen($x) < $randmax_bits) ? 128 - strlen($x) :  $randmax_bits;
        
$x .= str_pad(base_convert(mt_rand(0, pow(2,$maxbits)), 10, 2), $maxbits, "0", STR_PAD_LEFT);
     }

    
// break into fields
    
$a = array();
    
$a['time_low_part'] = substr($x, 0, 32);
    
$a['time_mid'] = substr($x, 32, 16);
    
$a['time_hi_and_version'] = substr($x, 48, 16);
    
$a['clock_seq'] = substr($x, 64, 16);
    
$a['node_part'] =  substr($x, 80, 48);
    
    
// Apply bit masks for "random or pseudo-random" version per RFC
    
$a['time_hi_and_version'] = substr_replace($a['time_hi_and_version'], '0100', 0, 4);
    
$a['clock_seq'] = substr_replace($a['clock_seq'], '10', 0, 2);

   
// Format output
   
return sprintf('%s-%s-%s-%s-%s',
       
str_pad(base_convert($a['time_low_part'], 2, 16), 8, "0", STR_PAD_LEFT),
       
str_pad(base_convert($a['time_mid'], 2, 16), 4, "0", STR_PAD_LEFT),
       
str_pad(base_convert($a['time_hi_and_version'], 2, 16), 4, "0", STR_PAD_LEFT),
       
str_pad(base_convert($a['clock_seq'], 2, 16), 4, "0", STR_PAD_LEFT),
       
str_pad(base_convert($a['node_part'], 2, 16), 12, "0", STR_PAD_LEFT));
}

?>

However, I think mimec's version is much more elegant.
mailbox1 at highhost dot net
23-Dec-2006 01:22
Also you may use this if you like it.

function uniqid2() {
return dechex(time()).dechex(mt_rand(1,65535));
}
wooshoofoo
07-Dec-2006 03:00
I'm not sure the previous function by mimec is really all that random.  For one thing, generating 8 small random 4 digit sequeces != generating one 32 digit sequence.
mimec
25-Aug-2006 10:36
Here is the correct version of a function generating a pseudo-random UUID according to RFC 4122:

<?php

function uuid()
{
    return
sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
       
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
       
mt_rand( 0, 0x0fff ) | 0x4000,
       
mt_rand( 0, 0x3fff ) | 0x8000,
       
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) );
}

?>

The version and variant is located at the MSB (most significant bits) of the time_hi_and_version and clock_seq_hi_and_reserved fields, not the LSB as in dholmes version.
admin at code-dynasty dot net
09-Jul-2006 05:46
I'm not too fond of the recommendation to use an MD5 of the unique ID for session IDs. It would be a better idea just to use uniqueid(rand(), true) without the MD5, because even though it's a rare circumstance, MD5 is a hash, not an encryption, which means it has collisions. Therefore you theoretically could have multiple users given the same session ID which could result in one user's ability to access another user's data.
dholmes at cfdsoftware dot net
09-May-2006 05:26
WARNING : I believe there are a couple of mistakes in the function provided just below by maciej dot strzelecki at gmail dot com. Namely, that in the two substr_replace() calls, the third parameters should respectively be 12 (instead of 11) and 6 (instead of 5).

Considering the importance of this function, I went to read RFC 4122 myself, and found the discrepancy. I therefore chose to write my own function, inspired by the previous one, but with a few enhancements detailed in the comments. On the downside, it might be slightly less easy to understand at first glance.

Please feel free to use it yourself. Thank you also in advance for any feedback at dholmes at cfdsoftware.net .

<?php

/**
 * Generates a Universally Unique IDentifier, version 4.
 *
 * RFC 4122 (http://www.ietf.org/rfc/rfc4122.txt) defines a special type of Globally
 * Unique IDentifiers (GUID), as well as several methods for producing them. One
 * such method, described in section 4.4, is based on truly random or pseudo-random
 * number generators, and is therefore implementable in a language like PHP.
 *
 * We choose to produce pseudo-random numbers with the Mersenne Twister, and to always
 * limit single generated numbers to 16 bits (ie. the decimal value 65535). That is
 * because, even on 32-bit systems, PHP's RAND_MAX will often be the maximum *signed*
 * value, with only the equivalent of 31 significant bits. Producing two 16-bit random
 * numbers to make up a 32-bit one is less efficient, but guarantees that all 32 bits
 * are random.
 *
 * The algorithm for version 4 UUIDs (ie. those based on random number generators)
 * states that all 128 bits separated into the various fields (32 bits, 16 bits, 16 bits,
 * 8 bits and 8 bits, 48 bits) should be random, except : (a) the version number should
 * be the last 4 bits in the 3rd field, and (b) bits 6 and 7 of the 4th field should
 * be 01. We try to conform to that definition as efficiently as possible, generating
 * smaller values where possible, and minimizing the number of base conversions.
 *
 * @copyright   Copyright (c) CFD Labs, 2006. This function may be used freely for
 *              any purpose ; it is distributed without any form of warranty whatsoever.
 * @author      David Holmes <dholmes@cfdsoftware.net>
 *
 * @return  string  A UUID, made up of 32 hex digits and 4 hyphens.
 */

function uuid() {
   
   
// The field names refer to RFC 4122 section 4.1.2

   
return sprintf('%04x%04x-%04x-%03x4-%04x-%04x%04x%04x',
       
mt_rand(0, 65535), mt_rand(0, 65535), // 32 bits for "time_low"
       
mt_rand(0, 65535), // 16 bits for "time_mid"
       
mt_rand(0, 4095),  // 12 bits before the 0100 of (version) 4 for "time_hi_and_version"
       
bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '01', 6, 2)),
           
// 8 bits, the last two of which (positions 6 and 7) are 01, for "clk_seq_hi_res"
            // (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d)
            // 8 bits for "clk_seq_low"
       
mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535) // 48 bits for "node" 
   
); 
}

?>
maciej dot strzelecki at gmail dot com
16-Apr-2006 08:09
This is an implementation of version 4 UUID, which is generating UUIDs from truly-random numbers.

<?php
/* Copyright 2006 Maciej Strzelecki

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */

function uuid()
{
   
// version 4 UUID
   
return sprintf(
       
'%08x-%04x-%04x-%02x%02x-%012x',
       
mt_rand(),
       
mt_rand(0, 65535),
       
bindec(substr_replace(
           
sprintf('%016b', mt_rand(0, 65535)), '0100', 11, 4)
        ),
       
bindec(substr_replace(sprintf('%08b', mt_rand(0, 255)), '01', 5, 2)),
       
mt_rand(0, 255),
       
mt_rand()
    );
}
?>
03-Apr-2006 08:16
if you're generating UUIDs you should really check out http://www.ietf.org/rfc/rfc4122.txt first ('version 4' UUID, chapter 4.4), as they are not completely random.

unpack> <time_sleep_until
Last updated: Fri, 04 Jul 2008
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites