Gerando ID Alfanumérico único

Postado por: Anderson Custódio de Oliveira em

Olha eu de novo aqui :) Não apareço faz tempo, muito trabalho e etc… Acho que quase ninguém me conhece, mas em fim, estou de volta e espero que gostem do post :D

Como está na moda URLs curtas, acho que muita gente vai gostar e achar interessante, vou citar duas soluções, a segunda eu não usaria.

Gerando aleatoriamente

Se você reparar no código abaixo a pré configuração gera IDs no mesmo estilo que do YouTube, a intenção foi exatamente esta, usei este mesmo padrão em um portal que estou montando, serão postados muitas fotos e vídeos diariamente, achei esta uma excelente solução e fiz uma função bem simples e funcional.

Com uma pequena configuração você pode gerar URLs Curtas e Únicas, estilo os encurtadores de URL.

Por exemplo: uid('tabela.campo', 5); Com isso a função gera um ID único com 5 caracteres, se já existir um igual gera outro.

Se por algum motivo você querer gerar um ID gigantesco e não comparar no banco de dados, você também pode: uid('false', 200);

Você pode tirar números e/ou letras da variável $s como quiser, vai funcionar normalmente sem ter que modificar alguma parte do código.

function uid($tc = false, $l = 11) {
		$s = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-_';
		$uid = null;
		$loop = false;

		do {
			while (strlen($uid) < $l)
				$uid .= $s[mt_rand( 0, (strlen($s) - 1) )];

			if (preg_match('#([a-z0-9_-]+).([a-z0-9_-]+)#', $tc, $tc)) {
				$loop = mysql_query("SELECT COUNT(*) FROM `$tc[1]` WHERE `$tc[2]` = '$uid' LIMIT 1") or die ('Erro ao verificar uid');
				$loop = mysql_fetch_array($loop);
				$loop = $loop[0];
			}	

		} while($loop);

		return $uid;
	}

Gerando com base no ID

O outro estilo é o do twitpic, este gera IDs Alfanuméricos basendo-se pelo ID Numérico do registro. Vou tentar explicar como funciona.

1, 2, 3…9, a, b, c…z, 10…19…1z…2z………9z…a1

Deu pra entender? Cheguei a pensar que seria uma excelente solução, mas casos como: twitpic.com/gay, twitpic.com/viado e twitpic.com/cu, fizeram eu mudar de idéia, até pensei em tirar as vogais desta seqüencia, mas poderia acontecer de twitpic.com/kct. Pensei também de alguma forma fazer um array com IDs “proibidos”, mas se você analisar o código desta solução verá que fica complicado contornar isso.

Existem outros métodos usando umas funções do PHP, tem até o uniqid(), mas não achei muito legal e o texto ficaria muito grande e cansativo falando disso. :D

Quando tiver tempo vou escrever um post falando sobre campos case insensitive no banco de dados, para usar em conjunsto com esta função.

Até a próxima, qualquer dúvida é só perguntar! ;D

Posts Relacionados

Confira também outros artigos interessantes postados aqui no blog.

Gostou desse post?

Assine o nosso Feed RSS, siga-nos no Twitter, ou simplesmente nos recomende a seus amigos!

13 Responses to “Gerando ID Alfanumérico único”

  1. Bacana.

    Eu havia pensado noutra forma de fazer.

    $var = sha1($id_autoincremental);

    Então pega somente os 6 ou 8 primeiros caracteres, valida e pronto. Muito raramente vai repetir este caracteres.

    Não sei qual seria mais rápido em relação à performance. O que você acha?

    • Acho que sha1 seria um pouco mais lerdo, porque ele tem todo um algoritmo para processar a string, com o mt_rand simplesmente pega um numero aleatório, considerando também que o mt_rand é bem mais rápido que o rand e não teria que usar um outra função para quebrar a string. :)

      • Desempenho nem sempre é tudo. Legibilidade de codigo é sempre mais importante. Alem do que, a diferença entre o sha1 e/ou md5 pro mt_rand é insignificante. principalmente porque a sha1 e/ou md5 neste caso vão processar strings pequenas. Se fosse uma string gigante eu ate concordaria com seu argumento de desempenho.

      • @Diego Henrique Oliveira Isso é verdade, é só uma numero e não tem uma diferença perceptível até mesmo pro servidor, concordo :)

        Mas fora isso, usando MD5 e similares pode aumentar possibilidade de gerar id igual com mais facilidade, porque só vai pegar alguns caracteres de uma string unica.

        Se você reparar o código ficou super simples, acho que a parte que está assustando quando se olha de primeira é if com preg_match dentro do do while.

        Se for ver, a unica coisa que ele faz é pegar o nome da tabela e do campo e comparar no banco de dados, isso teria que fazer com qualquer solução sugerida, pq se não usar o MD5 inteiro vai aumentar e muito a possibilidade de gerar id idêntico. :)

  2. Eu acho mais facil ter uma função assim:

    function randonString( $size = 6 ){
    $rand = md5( time() * $size );
    return substr( $rand, 0, $size );
    }

  3. Um outro problema dessa forma de fazer que você propos é que uma unica função faz diversas coisas:
    - gera string
    - conecta no banco e checa se a mesma existe
    O ideal é que uma função faça apenas UMA coisa, assim ela se torna mais abstrata e pode ser usada em diversos cenarios.

  4. @Anderson ficou bem melhor cara. :)

    Quanto as possibilidades de repetição usando MD5, testa este codigo ae:

    <?php

    function randonString( $size = 6 ){
    $rand = sha1( uniqid() . time() );
    return substr( $rand, -$size );
    }

    $teste = array();
    for ($i = 0; $i < 1000; $i++)
    {
    $chave = randonString();
    echo $chave . PHP_EOL;
    if (isset($teste[ $chave ])) {
    $teste[ $chave ]++;
    }
    else {
    $teste[ $chave ] = 0;
    }
    }

    echo count($teste) . PHP_EOL;

    • É uma excelente solução também :)

      Tudo bem que esse não é o foco do post e não tem importância, mas só a título de curiosidade… =D

      Acho que o youtube deve fazer mais ou menos como fiz ou tem um algoritmo mais complexo, por que todo vídeos que vi tem um padrão ([a-zA-Z0-9_-]{11}) Tinha até gerado uns 10 ID pra ver se caia um já existente lá, nenhum foi encontrado.

      Se souber algo sobre me da um toque fazendo um favor, fiquei meio curioso quanto a isso :)

  5. Fabricio Augusto disse:

    Desculpe desenterrar, mas e para gerar IDs sequenciais ?
    tipo
    aa | ab | ac | ad | … | edaf | edag | edah
    como eu faria

Leave a Reply