Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Gans

Gerar Serial único

Recommended Posts

Olá pessoal,

 

Estou construindo um sistema e irá usar um "serial" para ativar.

 

Gostaria de saber como posso gerar um serial único com letras e números com 16 dígitos?

 

XXXX-XXXX-XXXX-XXXX

 

Fiz um, mas gostaria que o serial fosse único e seguro.

<?php
$cr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$max = strlen($cr)-1;
$gera = null;
for($i=0; $i < 16; $i++) {
$gera .= $cr{mt_rand(0, $max)};
}
$gera = str_split($gera, 4);
echo "$gera[0]-$gera[1]-$gera[2]-$gera[3]";
?>

Alguém sabe um método mais fácil ou tenha uma lógica pronta?

 

Obrigado!

 

Edit:

 

Vejo também a opção de utilizar:

<?php
echo md5(uniqid(time()));
?>
O uniqid time é realmente único?

Compartilhar este post


Link para o post
Compartilhar em outros sites

O time é único a cada segundo, já que retorna o TIMESTAMP atual, ou seja, a cada segundo retorna um a mais.

 

Creio que a forma como ficou a última opção é melhor mesmo, mas olha o exemplo do manual do PHP.

 

$better_token = md5(uniqid(rand(), true));

http://br.php.net/uniqid

http://br.php.net/time

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estou construindo um sistema e irá usar um "serial" para ativar.

 

Você pode utilizar hash para fazer isso:

 

function getSerial( $name ){
    $a = hash( 'crc32' , 'chave secreta' );
    $b = hash( 'crc32' , sprintf( '%s%s' , md5( $name ) , md5( $a ) ) );
    $c = sscanf( sprintf( '%s%s' , $a , $b ) , '%4s%4s%4s%4s' );

    return vsprintf( '%s-%s-%s-%s' , $c );
}

var_dump( getSerial( 'Nome do cliente' ) ); //string(19) "71b0-8ee3-53b0-5a84"

Agora, se você precisar verificar se um serial é válido, você pode adicionar mais um módulo ao seu serial como verificador:

 

function getSerial( $name = null ){
    $a = hash( 'crc32' , 'chave secreta' );
    $b = hash( 'crc32' , sprintf( '%s%s' , md5( $name ) , md5( $a ) ) );
    $c = sscanf( sprintf( '%s%s' , $a , $b ) , '%4s%4s%4s%4s' );
    $d = 1;

    for ( $i = 0 ; $i < 4 ; $i++ )
        for ( $j = 0 ; $j < 4 ; $d += pow( ord( $c[ $i ]{ $j } ) , $i ) , $j++ );

    $c[ 4 ] = $d;

    return vsprintf( '%s-%s-%s-%s-%05x' , $c );
}

function validaSerial( $serial ){
    $c = sscanf( $serial , '%4s-%4s-%4s-%4s' );
    $d = 1;

    for ( $i = 0 ; $i < 4 ; $i++ )
        for ( $j = 0 ; $j < 4 ; $d += pow( ord( $c[ $i ]{ $j } ) , $i ) , $j++ );

    $c[ 4 ] = $d;

    return !strcmp( $serial , vsprintf( '%s-%s-%s-%s-%05x' , $c ) );
}

$serial = getSerial( 'Nome do cliente' );

if ( validaSerial( $serial ) ){
    printf( 'O serial %s é válido.' , $serial );
} else {
    print 'Serial inválido.';
}

A saída deverá ser: O serial 71b0-8ee3-53b0-5a84-154ace é válido.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa.. então Matias Rezendeo ruim que pelo MD5 gera uma quantidade muito grande de números e eu queria mais letras mesmo...

 

João Batista Neto, obrigado pelo codigo, mas pensando aqui, acho que não preciso de um codigo tão complexo já que não precisa validar ele e ficará salvo no banco de dados.

 

Pensei em fazer algo mais ou menos assim:

<?php
$cr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$max = strlen($cr)-1;
$gera = null;
for($i=0; $i < 16; $i++) {
$gera .= $cr{mt_rand(0, $max)};
}
$gera = str_split($gera, 4);
$serial = "$gera[0]-$gera[1]-$gera[2]-$gera[3]";

$exe = mysql_query("SELECT * FROM codigos WHERE codigo = '$serial'");
$cont = mysql_num_rows($exe);

if($cont != 0) {
// EXECUTA NOVAMENTE O SCRIPT DO SERIAL E A VERIFICAÇÃO.
}
else {
	$sql = mysql_query("INSERT INTO `codigos` (`id`, `codigo`, `ativo`) VALUES ('', $serial, 0);");
	echo "Serial Gerado com Sucesso!<br />Serial: $serial";
}
?>

Porem eu não sei como posso executar o codigo novamente se já existir o serial cadastrado no banco de dados...

 

Obrigado pelas respostas!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Alguém sabe como posso por um "looping" no código até o código gerado não ter no banco de dados sem atualizar a pagina?

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Basta Usar uma Flag

<?php
$flag=0;
do{
$cr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$max = strlen($cr)-1;
$gera = null;
for($i=0; $i < 16; $i++) {
$gera .= $cr{mt_rand(0, $max)};
}
$gera = str_split($gera, 4);
$serial = "$gera[0]-$gera[1]-$gera[2]-$gera[3]";

$exe = mysql_query("SELECT * FROM codigos WHERE codigo = '$serial'");
$cont = mysql_num_rows($exe);

if($cont == 0) {
        $sql = mysql_query("INSERT INTO `codigos` (`id`, `codigo`, `ativo`) VALUES ('', $serial, 0);");
        echo "Serial Gerado com Sucesso!<br />Serial: $serial";
        $flag = 1;
}
}while($flag==1);
?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.