PHP é à quinta-feira – Gerar uma password
Boas. A nível de direitos sobre o código, devo remeter-vos para o meu primeiro artigo desta rubrica.
Esta semana trago-vos um conjunto de funções que os ajudarão a gerar uma password (ou qualquer outra string de caracteres aleatórios).
A princípio pode-vos parecer muito grande e a verdade é que é possível reduzir a segunda função de outras formas, mas penso que esta é mais fácil de entender e personalizar.
<?php function generatePassword($length = 8 ) { $pwd = ''; if($length > 0) { for($i=0;$i<$length;$i++) { mt_srand((double)microtime() * 1000000); $x = mt_rand(1,65); $pwd .= assignValue($x); } } return $pwd; } function assignValue($x) { switch($x) { case 1 : { $r = "a"; } break; case 2 : { $r = "b"; } break; case 3 : { $r = "c"; } break; case 4 : { $r = "d"; } break; case 5 : { $r = "e"; } break; case 6 : { $r = "f"; } break; case 7 : { $r = "g"; } break; case 8 : { $r = "h"; } break; case 9 : { $r = "i"; } break; case 10: { $r = "j"; } break; case 11: { $r = "k"; } break; case 12: { $r = "l"; } break; case 13: { $r = "m"; } break; case 14: { $r = "n"; } break; case 15: { $r = "o"; } break; case 16: { $r = "p"; } break; case 17: { $r = "q"; } break; case 18: { $r = "r"; } break; case 19: { $r = "s"; } break; case 20: { $r = "t"; } break; case 21: { $r = "u"; } break; case 22: { $r = "v"; } break; case 23: { $r = "w"; } break; case 24: { $r = "x"; } break; case 25: { $r = "y"; } break; case 26: { $r = "z"; } break; case 27: { $r = "0"; } break; case 28: { $r = "1"; } break; case 29: { $r = "2"; } break; case 30: { $r = "3"; } break; case 31: { $r = "4"; } break; case 32: { $r = "5"; } break; case 33: { $r = "6"; } break; case 34: { $r = "7"; } break; case 35: { $r = "8"; } break; case 36: { $r = "9"; } break; case 37: { $r = "A"; } break; case 38: { $r = "B"; } break; case 39: { $r = "C"; } break; case 40: { $r = "D"; } break; case 41: { $r = "E"; } break; case 42: { $r = "F"; } break; case 43: { $r = "G"; } break; case 44: { $r = "H"; } break; case 45: { $r = "I"; } break; case 46: { $r = "J"; } break; case 47: { $r = "K"; } break; case 48: { $r = "L"; } break; case 49: { $r = "M"; } break; case 50: { $r = "N"; } break; case 51: { $r = "O"; } break; case 52: { $r = "P"; } break; case 53: { $r = "Q"; } break; case 54: { $r = "R"; } break; case 55: { $r = "S"; } break; case 56: { $r = "T"; } break; case 57: { $r = "U"; } break; case 58: { $r = "V"; } break; case 59: { $r = "W"; } break; case 60: { $r = "X"; } break; case 61: { $r = "Y"; } break; case 62: { $r = "Z"; } break; case 63: { $r = "!"; } break; case 64: { $r = "?"; } break; case 65: { $r = "%"; } break; } return $r; } ?>
Modo de utilização:
Como sempre, é bastante simples e intuitivo, segue um exemplo de como gerar uma password com 8 caracteres e outra com 15.
<?php $pwd1 = generatePassword(); $pwd2 = generatePassword(15); ?>
Nota: Se acrescentarem ou retirarem algum caracter do função assignValue(), lembrem-se de alterar o número máximo na função generatePassword() na linha onde tem “$x = mt_rand(1,65); ”.
Notem que para não haver problemas, convém que na função assignValue() os números sejam sequenciais, ou seja, que não salte de um número para outro que não o seguinte.
Qualquer dúvida ou sugestão, estão completamente à vontade.
Como vou entrar em exames (para a semana), etc., se quiserem enviar as vossas propostas para esta rubrica, agradeço, pois será difícil escrevê-la até ao final de Julho.
Este artigo tem mais de um ano
Acho que o código é demasiado comprido…
Eu tenho algo semelhante, mas que acho que ainda não está a 100%:
function aleatorio($contador)
{
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&/()=?*@£§{[]}«»,.-;:_";
srand((double)microtime()*1000000);
$i = 0;
$pass = '';
while ($i <= $contador) {
$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$pass = $pass . $tmp;
$i++;
}
return $pass;
}
// Para gerar uma password:
aleatorio(10);
Que achas Bruno acerca deste método?
Como tinha dito, mostrei daquela forma para ser de mais fácil compreensão, mas obviamente o teu método é mais curto e igualmente útil e eficaz.
Está demasiado complicado. É coisa que se faz bem em 6 ou 7 linhas. Se me der na telha depois meto aqui um exemplo.
Mete aqui um exemplo… Ficamos todos a ganhar e agradecemos 🙂
excelente tut, eu em breve vou ter que abrir php, planeio focar me nestes tuts do pplware eheh.
mt obrigado por dispensares o teu tempo pra os escrever 😉
Bruno, desculpa que te diga, mas isso é um exagero.
Já para não falar na falta de “performance” de todo esse código.
Imagina uma linha assim:
echo substr(str_shuffle(“0123456789abcdefghijklmopqrstuvwxyACDEFGHJKLMOPQRSTUVWXY!?%”), 0, 8);
Aí tens uma password com 8 caracters 🙂
Cumprimentos.
Desculpa que te diga eu, mas achas que um substr() de um str_shuffle() é mais rápido que um case? a nível de velocidade, o que apresento é mais rápido que qualquer outro aqui apresentado 🙂
Bem, és novo a programar e é normal que profiras tais afirmações, tudo bem eu compreendo.
Só para tirar as dúvidas aos leitores a tua função demorou:
0.0317189693451 segundos
a minha (a primeira) demorou:
0.000108003616333 seconds
Ambas a gerar passwords com 8 caracteres.
Cumprimentos.
Ah e atenção, eu não disse que um substr() de um str_shuffle() era mais rápido que um case. É mais rápido no seu todo em comparação com as funções que fizeste.
Quero deixar claro que não estou a querer rebaixar o teu trabalho, apenas estou a tentar explicar o que a meu ver é mais correcto.
Há uma coisa que aprendi aqui há uns anos quando comecei que foi manter as coisas o mais simples e funcionais possiveis.
Cumprimentos.
Boas,
Tens razão, realmente não considerei que na função tenho o rand, peço desculpa mas a esta hora já não penso a 100% 🙂
Mas a diferença que colocaste deixou-me curioso pelo que fiz eu os testes e o meu deu-me:
0.000194072723389
enquanto o teu deu-me:
0.0000228881835938
O que continua a ser relevante mas não tanto como o que tinhas mostrado inicialmente.
De qualquer das formas, penso que fui bem claro no artigo ao explicar que não era a forma ideal nem mais rápida de fazer o que propus, mas sim a de mais fácil compreensão e alteração para quem estivesse interessado em aprender/usar.
Não te preocupes porque programo há mais de 8 anos e tenho perfeitamente noção do que digo 🙂 o que disse não estava errado, simplesmente não considerei o rand, mas também não disse que o tinha feito 😀
Ficou ali um espaço enorme lol
Bem deixo aqui a anterior novamente…
echo substr( str_shuffle( “0123456789abcdefghijklmopqrstuvwxyACDEFGHJKLMOPQRSTUVWXY!?%” ), 0, 8 );
e uma outra…
echo substr( md5( uniqid( mt_rand(), true ) ), 0, 8 );
Esta última tem o senão de não gerar caracteres especiais.
Cumprimentos.
A função que aqui apresentaste mostra é que conheces muito pouco sobre PHP e sobre a melhor forma de escrever código aproveitando as funcionalidades oferecidas pela linguagem, que em 99% dos casos são mais eficientes que qualquer função que tu escrevas (porque são escritas e compiladas em C, ao contrário das tuas, que são interpretadas em runtime…).
E depois ainda teres o descaramento de dizer (não sei bem baseado em quê) que a tua função (na realidade 2 funções com 80 linhas :O)) é mais rápida que o “one-liner” apresentado pelo Ice mostra que ainda estás muito crú na arte de programar, o que me faz questionar o porquê de teres uma rúbrica de programação no PPLWare.
Keep It Simple, Stupid! Complicar para quê quando as melhores soluções são as mais simples e elegantes? (que por sua vez também são bem mais fáceis de perceber…)
1º Não mereces resposta, se vens aqui só para atacar, podes continuar a falar.
2º Porque falaste de coisas que não disse (tens de ler com mais atenção as coisas) e puseste em causa a minha qualidade assim como a do Pplware, senti que deveria deixar claro que estás errado, para os mais desatentos.
3º Os insultos denigrem a tua imagem e como tal não deverias recorrer aos mesmos, porque simplesmente te fica mal, assim como o facto de não teres lido com atenção o artigo nem os comentários.
4º Caso tenhas lido com atenção, tenho pena porque a tua interpretação é muito fraca.
1º Não vim para aqui atacar! Vim aqui criticar, porque gosto do PPLWare e acho que esta rúbrica prima pela falta de qualidade.
2º O que é que eu disse que tu disseste que tu não tenhas dito? Não sou mentiroso, por isso justifica-te.
3º Não te insultei! Se estás a falar do Keep It Simple, Stupid! tenho uma referência para ti: http://en.wikipedia.org/wiki/KISS_principle
Se ficaste ofendido tenho pena, porque não era minha intenção.
4º Tenho pena que não saibas aceitar uma crítica cujo objectivo não é ser destrutiva.
1º Ok então, um pouco de simpatia não ficaria nada mal.
2º Nunca disse que a minha função era mais rápida que a dele, disse sim que o case era, e apesar de me ter referido à função, não me estava a lembrar do rand, até porque não uso esta função, simplesmente escrevi para ser de simples leitura/edição, etc. como referi e estou farto de referir pois não pareces compreender!
3º Insultaste-me ao chamar-me mau programador e insultaste-me pela sugestão de que eu não merecia esta rúbrica no Pplware
4º Não é destrutivo? Bem, se isso foi construtivo, não quero ver destrutivo…
Nesse ponto tens razão.
Fui um pouco bruto e abrupto no que disse e podia ter manifestado a minha opinião de outra forma.
Por isso peço desculpa.
Não te queria (nem quero) insultar, mas nos vários posts que esta rubrica tem, tens apresentado quase sempre funções sub-óptimas, pouco eficientes e nada elegantes, quando há formas mais simples de fazer o mesmo. Na maioria das vezes basta googlar o assunto e encontras N funções melhores e que fazem exactamente o mesmo ou mais.
Só queria mais “qualidade” no código apresentado. Não me leves a mal. 🙂
No comentário anterior esqueci-me completamente de referir outro grande *problema* na tua implementação, que mostra pouco conhecimento sobre o que realmente fazem as funções que estás a utilizar.
Estás a executar esta linha:
mt_srand((double)microtime() * 1000000);
dentro do for, o que além de ser completamente desnecessário é extremamente ineficiente e atrasa a função.
A função mt_srand() serve para “semear” o gerador de números aleatórios, coisa que só precisas de fazer uma única vez por script.
Fazeres isso todas as vezes que geras um número aleatório não aumenta a “pseudo-aleatoriedade” dos números gerados (sinceramente nem sei se não a reduzirá!) e reduz a eficiência da função.
Também não percebo o motivo de existir da função assignValue(), uma vez que declarando um array (possivelmente estático, dentro da função generatePassword()) cujas keys seriam os números (o argumento de entrada da assignValue()) e os valores as letras a devolver, podes facilmente simular uma hashtable para usar no ciclo “for” que insistes em usar, o que elimina o overhead da chamada da função assignValue() e torna o algoritmo mais rápido.
O facto de chamar o seed dentro do ciclo é apenas para assegurar uma maior aleatoriedade (que sim, acaba por existir, lê sobre o assunto, não te quero explicar que o “aleatório” não existe nos computadores, é calculado e ao atribuir um valor diferente à seed, a probabilidade de sair outro número igual é menor) do valor gerado pelo rand(). Se era necessário? talvez não. Se faz o que deve? Sim.
Não precisas de me explicar o que cada função do PHP faz, conheço-as bem. Lido todos os dias com elas.
Como expliquei muitas vezes, passo a explicar novamente, talvez leias agora:
A função AssignValue() existe apenas para facilitar quem queira adicionar/editar possíveis caracteres de uma password.
Outra nota para ti e outros que se acham grandes programadores: Esta rúbrica não é para programação avançada. É sim para ajudar quem se inicia a ter algo por onde pegar. As funções não estão optimizadas. Se apresentar algo na sua melhor forma a quem quer aprender, não aprende é simples. Se não consegues interiorizar isso, tudo bem, azar o teu.
Eu já perco tempo com isto a criar funções de forma mais simplificada para ajudar, talvez queiras tu pegar e ajudar na rubrica? Não? Então criticas só porque sim? É dizer e fugir?
Não fales à toa. Lê o primeiro artigo, percebe as coisas.
Muito menos julgues algum programador por uma ou duas funções que faça, ainda por cima com o objectivo que estas tiveram.
Desculpa, mas estás-te a contradizer.
Acabaste de dizer:
“Outra nota para ti e outros que se acham grandes programadores: *Esta rúbrica não é para programação avançada*. É sim para ajudar quem se inicia a ter algo por onde pegar. As funções não estão optimizadas. Se apresentar algo na sua melhor forma a quem quer aprender, não aprende é simples. Se não consegues interiorizar isso, tudo bem, azar o teu.”
Mas no primeiro post desta rubrica (https://pplware.sapo.pt/2009/04/09/php-e-a-quinta-feira-converter-um-array-num-object/) disseste:
“Nesta rubrica vou falar pouco (à parte desta “primeira”), e vou-vos deixar funções que me são muito úteis no dia-a-dia, que penso que poderão ser também para vocês.
*Esta rubrica não será mais destinada a quem quer aprender a programar*, porque para aprender a programar têm de pegar e perceber primeiro algoritmia, só depois passar para uma linguagem de programação. *Será sim destinada a quem já sabe e consegue programar em PHP e deseja/necessita/é útil ter umas funções e/ou classes (simples ou complexas) “gerais” que se consigam utilizar nos mais diversos projectos*.”
Ora se esta rubrica é mais avançada (como disseste no primeiro post) e não é para ensinar algoritimia, mas sim para “fornecer funções e/ou classes gerais para utilizar nos mais diversos projectos”, então devias apresentar funções optimizadas, e ensinar a fazer as coisas “the right way”.
Bem, não me expliquei bem no primeiro artigo, agora que mo mostras… realmente o que quis dizer foi que não era para aprender no sentido de início de programação como quem ainda nem algoritmia sabe e salta para uma linguagem, mas sim aprender no sentido de já perceber algoritmia e da linguagem e aí sim, aprender com estas funções, ou seja, para servirem de base.
De qualquer das maneiras, não acho útil mostrar funções / scripts completamente optimizados, porque dessa forma não há nada para aprender.
Mas de qualquer das formas, deixaste uma questão pertinente.
PARA TODOS OS UTILIZADORES QUE GOSTAM DESTA RUBRICA:
– Preferem funções que possam pegar para servirem de base às vossas e poderem aprender a melhorá-las (como tenho feito até agora)?
OU
– Preferem funções optimizadas?
Obrigado pela tua convicção, pois estava convencido que tinha sido explícito no primeiro artigo… sou eu que já não ando a ver bem as coisas…
Eu pessoalmente, como já deves ter percebido, gostava de ver aqui funções o mais eficientes possível e de preferência que apresentem a melhor forma de resolver o problema apresentado.
Mas não sei o que a maioria dos leitores prefere, por isso esperemos que sejam apresentadas mais opiniões de forma a que esta rubrica seja o que os leitores pretendem e tenha o nível de qualidade o mais alto possível.
Boa tarde, gosto muito desta rubrica, com ela aprendo uns pequenos truques, para construir a minha base em php.
Digo para já que não concordo o facto de porem o autor a ter de responder pelo seu código, visto que este blog não é focado apenas em php. É uma função, que faz o que é necessário, e ajuda quem quer implementar algo do género na sua aplicação.
Contudo, concordo com o Tiago Nunes, que gostaria *também* de ter exemplos e explicações de funções óptimas/eficientes, pois, começaria a levar-nos para um campo que é bastante interessante, bem como veriamos porque é que uma dada função é óptima.
Viva,
Também programo em php á alguns anos e pessoalmente não a faria assim, mas não a invalida nem necessita de tantas criticas como está a ser alvo.
Existem imensas formas de se conseguir fazer algo. umas mais eficientes outras mais simples de perceber, e o que ele tentou mostrar, pelo que percebi era algo simples de se perceber, e para quem está a Iniciar em php, decerto que esta forma será mais simples de se perceber. Para quem já programa pode parecer que não, mas para quem se inicia, e quer perceber o que faz, dividir as coisas é a forma mais indiciada, tal como ele fez.
O que poderia talvez ter colocado seria outras formas. mas, no meu ver, será mais engraçado quem comenta, colocar outras formas de o fazer, sem ter de criticar negativamente o que já foi feito.
Continuação de Bom trabalho
Uma pessoa que me compreendeu bem 😉
Qual seria a tua resposta à minha pergunta?
Penso que o ideal seria, criar algo simples de se perceber, e os pessoal que comenta, se achar por bem Enriquecer o que foi colocado.
Pois é impossível agradar a todos apenas com 1 post sobre 1 assunto, pecando sempre por excesso ou por defeito. 🙂
Eu compreendo o Bruno. Ninguem aprendeu a programar sem começar pelos if’s, for’s, while’s etc. É verdade que o código está tudo menos optimizado, mas para quem está a aprender não poderia estar mais simples!
Serve muito bem para se aprenderem as bases da programação. A optimização do código já um assunto de nível mais avançado e seria irreal apresentar um tutorial que se apresenta simples apenas com uma ou duas linhas de código!
Para mim foi um excelente exemplo onde qualquer iniciante pode entender algumas bases!
Bom trabalho Bruno! 😉
Com tudo isto , só me leva a dizer … Ainda bem que todos somos diferentes a programar…. Afinal todos diferentes mas todos iguais … Continuação de Bom Trabalho Bruno .
Eu acho que se deve aprender logo de inicio os bons métodos de programação, se cada acção for bem comentada tudo será entendido e não há a cá código para iniciantes ou profissionais, ou se aprende ou não se aprende.
Ora bem,
Vou ser imparcial nisto, como tal:
Continuar código não optimizado: 3
Mudar para código optimizado: 2
Esperava mais comentários… assim é uma decisão com poucos “eleitores”
Eu voto pelo código optimizado. Lamento se deixo algum trecho de egoísmo para com os leitores principiantes na área, mas penso que cabe a cada um pronunciar-se mediante aquilo que será mais benéfico para si mesmo. Visito este site para proveito próprio e não alheio, por isso fica aqui a minha opinião.
Continua o bom trabalho Bruno.
Agora está empatado… alguém desempata isto? Têm até à próxima terça-feira 🙂
Venho desempatar isto e o meu voto vai para a simplicidade.
Penso que o pplware (sem desrespeito) não é o um baú de bocados de código que se copiam e se colam no nosso trabalho. Considero esta rubrica boa para os principiantes, mas quando se começa a dominar a linguagem, a curiosidade das pessoas deve leva-las a estudar mais a fundo a linguagem que se gosta e portanto ler a api da mesma. É assim que se chega a algum lado e não a ler pedaços de código em blogs.
Desculpa mas não consegui perceber se o teu voto vai para a simplicidade do código (código optimizado) ou simplicidade de compreensão (código não optimizado). 🙂
simplicidade de compreensão.
quem já domina a linguagem não precisa de vir cá copiar códigos. Se o quiser fazer pode muito bem copiar o código de outros projectos que já fez.
Ok, agora compreendi e, como deves saber, concordo.
Estado:
Continuar código não optimizado: 4
Mudar para código optimizado: 3
Boas Bruno Bernardino, é bom ver que continuas com a rubrica do PHP. BOm, convenhamos que o código não está optimizado (para ser sincero, aquele switch faz-me arepios!), mas também é verdade que alertaste logo no inicio que o código era mais para perceber o funcionamento.
Eu compreendo, a falta de tempo nunca está a nosso favor. Eu também estou na mesma situação, senão até tinha escrito um artigo, ficam aqui as sugestões que tinha pensado:
* cache de resultados da base de dados/ficheiros
* estruturas de dados básicas POO em PHP (filas, pilhas, …) para demonstrar o poder dos arrays.
Ficam as dicas, pode ser que faça um ‘clique’ nalguma cabecinha 😉
Cumps.
Boas,
Em relação às sugestões para artigos que mencionaste, mais específicamente ao artigo sobre “estruturas de dados básicas POO em PHP (filas, pilhas, …) para demonstrar o poder dos arrays”, lembrei-me que também era muito bom dar a conhecer aos leitores algo que muitos programadores de PHP desconhecem e facilita imenso a vida, que á a Standard PHP Library ( SPL: http://pt.php.net/manual/en/book.spl.php ).
Entre muitas outras coisas, fornece classes para representar e manipular as estruturas de dados que referiste e muitas outras ( Stacks, Queues, Listas Bi-ligadas, Heaps, etc.). Link: http://pt.php.net/manual/en/spl.datastructures.php
Não fazia a mínima ideia que isso existia! Mas sem dúvida um bom leque de “ferramentas” para quem gosta de usar POO em PHP, tal como por exemplo, o java que já tem isso integrado na framework.
obrigado pelo link 😉
Por acaso já tinha visto mas nunca utilizei. Realmente parece-me que dará bastante jeito. Obrigado pela dica.
Já que foram pedidas opiniões, eu concordo plenamente com o Tiago Nunes e com a solução por ele apresentada. A função apresentada pelo Bruno complica o que é simples e, na minha opinião, não ajuda a compreensão dos menos experientes, pelo contrário.
Acho que para se aprender, deve-se aprender sempre pelo código mais simples possível.
Continuar código não optimizado: 4
Mudar para código optimizado: 4
Por este andar, vou ter de fazer uma semana optimizado, outra não optimizado 🙂
Espero que tenhas reparado no reply que fiz lá acima num comentário do Tiago Nunes.
Fica aqui o link para ele: https://pplware.sapo.pt/2009/07/02/php-e-a-quinta-feira-gerar-uma-password/#comment-221391
Continuar código não optimizado: 4
Mudar para código optimizado: 5
Desculpa, não tinha reparado! 🙂
Apesar de eu não ser nenhum pro em PHP também gostava de aqui ver funções e/ou classes verdadeiramente eficientes e optimizadas. A meu ver é essa a melhor (única?) maneira de aprender a programar e a fazer as coisas bem feitas.
Abraços.
Offtopic:
Podiam ter anunciado aqui no pplware o lançamento da versão final 5.3 do PHP (saiu a semana passada).
É das versões mais aguardadas, devido às numerosas novas (e desejadas!) funcionalidades que trás. 🙂
Continuar código não optimizado: 4
Mudar para código optimizado: 6
Ainda gostava de ver votos na ordem das centenas, senão torna-se um pouco desesperante…
Relativamente ao PHP 5.3, pois, estou em exames, peço desculpa mas não consigo fazer tudo.
Não queres escrever tu um artigo sobre isso?
Pois, eu também estou em exames… 🙁
Se arranjar um bocadinho livre talvez escreva qualquer coisa a realçar as novidades desta nova versão, mas não prometo nada. 🙂
LOL tanta discussão e nenhum dos dois com razão….