Eu quero criar uma seqüência exata de 5 caracteres aleatórios com a menor possibilidade de ser duplicado. Qual seria a melhor forma de o fazer? Obrigado.
Usando Random::alphanumericString($length)você pode obter strings com 0-9a-zA-Z que são originadas de dados aleatórios criptograficamente seguros.
caw de
Respostas:
162
$rand = substr(md5(microtime()),rand(0,26),5);
Seria meu melhor palpite - a menos que você também esteja procurando por caracteres especiais:
$seed = str_split('abcdefghijklmnopqrstuvwxyz'.'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.'0123456789!@#$%^&*()');// and any other characters
shuffle($seed);// probably optional since array_is randomized; this may be redundant
$rand ='';foreach(array_rand($seed,5)as $k) $rand .= $seed[$k];
Nota: incremental significa mais fácil de adivinhar; Se você estiver usando isso como um salt ou um token de verificação, não faça isso. Um salt (agora) de "WCWyb" significa que daqui a 5 segundos é "WCWyg")
O problema de usar, md5()entretanto, é que você obtém uma string composta de um conjunto de 16 caracteres (10 dígitos e aaté f, ou seja, 4 bits por caractere da string). Isso pode ser suficiente para alguns fins, mas pode ser muito pouco para fins criptográficos (cinco caracteres de 16 símbolos = 16 ^ 5 = 20 bits = 1048576 possibilidades).
Arco de
3
array_rand($seed, 5)retornará a chave da matriz, não o valor, então seu código não funcionará
alumi
1
Eu acho que usar uma função hash criptográfica para gerar caracteres aleatórios é pelo menos inapropriado.
gronostaj
É possível também incluir ", 'e barra invertida $charset? Preciso usar sequências de escape para incluir esses caracteres?
Mai,
1
O segundo trecho nem usa o $lenparâmetro de entrada ... você esqueceu?
TechNyquist
76
Se os forloops estiverem faltando, aqui está o que eu gosto de usar:
Solução interessante ... muito concisa, embora eu me pergunte se isso é mais rápido ou mais lento do que usar para. No entanto, não posso ser incomodado para fazer o benchmark :-)
@ user2826057: str_shuffle('ab')daria abou bamas nunca aa. Adicionar o str_repeatpermite isso. Dito isso, a solução que dei não é realmente séria ... embora funcione.
Mateus
2
Há 1/60466176 de chance de isso acontecer, assumindo que o RNG esteja uniformemente distribuído.
Mateus,
1
Isso é perfeito para nosso caso de uso de geração de códigos de voucher. Nós removemos confundindo caracteres, como l, i, 1, 0, O, etc e fora de 500 vales não tenho duplicatas.
Luke Cousins
25
Uma maneira rápida é usar os caracteres mais voláteis da função uniqid .
O seguinte deve fornecer a menor chance de duplicação (você pode querer substituir mt_rand()por uma fonte de número aleatório melhor, por exemplo, de /dev/*randomou de GUIDs):
Primeiro exemplo mais inteligente com $ result. = $ Characters [mt_rand (0, strlen ($ characters) -1)]
hamboy75
Nesse caso, você deve determinar o comprimento de antemão e armazená-lo em uma variável, pelo menos. Usar strlen()em um loop é uma sobrecarga desnecessária, especialmente se você já sabe que o conjunto de caracteres não mudará nesse meio tempo.
Arco de
Eu duvido, php é otimizado, de qualquer forma é uma opção :)
hamboy75
7
Sempre uso a mesma função para isso, geralmente para gerar senhas. É fácil de usar e útil.
Eu acredito que usar funções hash é um exagero para uma tarefa tão simples como gerar uma sequência de dígitos hexadecimais aleatórios. dechex+ mt_randfará o mesmo trabalho, mas sem trabalho criptográfico desnecessário. str_padgarante um comprimento de 5 caracteres da string de saída (se o número aleatório for menor que 0x10000).
A probabilidade duplicada depende mt_randda confiabilidade de. Mersenne Twister é conhecido por sua aleatoriedade de alta qualidade, então deve se encaixar bem na tarefa.
Eu também não sabia fazer isso até que pensei em usar PHP array. E tenho certeza de que essa é a maneira mais simples de gerar uma string ou número aleatório com array. O código:
Como Archimedix apontou, isso não garante o retorno da "menor possibilidade de duplicação", pois o número de combinações é baixo para o intervalo de caracteres fornecido. Você precisará aumentar o número de caracteres ou permitir caracteres extras (especiais) na string. A primeira solução seria preferível, eu acho, no seu caso.
Usar time()é até 1 milhão de vezes mais previsível do que microtime().
Arco de
Observe também meus comentários à resposta de Brad, o maior problema é que o hash gerado é uma representação hexadecimal que consiste em 16 caracteres válidos, deixando apenas 1.024 variações para $str.
Arco de
@Archimedix, talvez, mas o OP não pediu segurança, a questão foi definida para ter um algoritmo gerador de string consistindo de uma combinação de 5x26 caracteres diferentes, evitando duplicatas. Provavelmente é para um número de referência de confirmação em um processo de registro (ou processo de faturamento) ou algo assim
Yanick Rochon
Foi o meu entendimento de que ele fez pedir menos possibilidade de ser duplicada , e isso tem 0,1% de probabilidade (1 em 1024) que poderia ter sido quase 1 em 1 bilhão.
Arco de
no entanto, se você precisa gerar uma chave de referência de 5 caracteres e dar-lhe um cliente / cliente, você não deseja dar a eles " ˫§»⁋⅓" simplesmente porque é mais seguro ... você aumenta sua chave de referência para 7 ou mais caracteres . (BTW: correção em meu comentário anterior, é 5x36 caracteres)
function cvf_ps_generate_random_code($length=10){
$string ='';// You can define your own characters here.
$characters ="23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";for($p =0; $p < $length; $p++){
$string .= $characters[mt_rand(0, strlen($characters)-1)];}return $string;}
A nova função do PHP password_hash()(*> = PHP 5.5) está fazendo o trabalho para a geração de conjuntos decentemente longos de letras maiúsculas e minúsculas e números.
Dois concat. strings antes e depois da password_hashfunção $ random são adequadas para alteração.
Os parâmetros para $random()* ($ a, $ b) são na verdade substr()parâmetros. :)
NOTA: isso não precisa ser uma função, pode ser uma variável normal também .. como um singleliner desagradável, como este:
Dica profissional - inclua alguma explicação sobre como sua resposta resolve o problema do OP e por que ela pode ser diferente das outras respostas já fornecidas.
0-9a-zA-Z
?Random::alphanumericString($length)
você pode obter strings com 0-9a-zA-Z que são originadas de dados aleatórios criptograficamente seguros.Respostas:
Seria meu melhor palpite - a menos que você também esteja procurando por caracteres especiais:
Exemplo
E, para um baseado no relógio (menos colisões, pois é incremental):
Nota: incremental significa mais fácil de adivinhar; Se você estiver usando isso como um salt ou um token de verificação, não faça isso. Um salt (agora) de "WCWyb" significa que daqui a 5 segundos é "WCWyg")
fonte
md5()
entretanto, é que você obtém uma string composta de um conjunto de 16 caracteres (10 dígitos ea
atéf
, ou seja, 4 bits por caractere da string). Isso pode ser suficiente para alguns fins, mas pode ser muito pouco para fins criptográficos (cinco caracteres de 16 símbolos = 16 ^ 5 = 20 bits = 1048576 possibilidades).array_rand($seed, 5)
retornará a chave da matriz, não o valor, então seu código não funcionará"
,'
e barra invertida$charset
? Preciso usar sequências de escape para incluir esses caracteres?$len
parâmetro de entrada ... você esqueceu?Se os
for
loops estiverem faltando, aqui está o que eu gosto de usar:fonte
str_shuffle('ab')
dariaab
ouba
mas nuncaaa
. Adicionar ostr_repeat
permite isso. Dito isso, a solução que dei não é realmente séria ... embora funcione.l
,i
,1
,0
,O
, etc e fora de 500 vales não tenho duplicatas.Uma maneira rápida é usar os caracteres mais voláteis da função uniqid .
Por exemplo:
fonte
Você pode tentar simplesmente assim:
mais detalhes: http://forum.arnlweb.com/viewtopic.php?f=7&t=25
fonte
O seguinte deve fornecer a menor chance de duplicação (você pode querer substituir
mt_rand()
por uma fonte de número aleatório melhor, por exemplo, de/dev/*random
ou de GUIDs):EDIT:
Se você está preocupado com a segurança, realmente, não use
rand()
oumt_rand()
, e verifique se o seu dispositivo de dados aleatórios é na verdade um dispositivo que gera dados aleatórios , não um arquivo regular ou algo previsível como/dev/zero
.mt_rand()
considerado prejudicial:https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php
EDITAR: Se você tiver suporte a OpenSSL em PHP, poderá usar
openssl_random_pseudo_bytes()
:fonte
strlen()
em um loop é uma sobrecarga desnecessária, especialmente se você já sabe que o conjunto de caracteres não mudará nesse meio tempo.Sempre uso a mesma função para isso, geralmente para gerar senhas. É fácil de usar e útil.
fonte
Parece que str_shuffle seria um bom uso para isso. Semeie o shuffle com os personagens que você quiser.
fonte
fonte
Se não houver problema em receber apenas letras AF, aqui está minha solução:
Eu acredito que usar funções hash é um exagero para uma tarefa tão simples como gerar uma sequência de dígitos hexadecimais aleatórios.
dechex
+mt_rand
fará o mesmo trabalho, mas sem trabalho criptográfico desnecessário.str_pad
garante um comprimento de 5 caracteres da string de saída (se o número aleatório for menor que 0x10000).A probabilidade duplicada depende
mt_rand
da confiabilidade de. Mersenne Twister é conhecido por sua aleatoriedade de alta qualidade, então deve se encaixar bem na tarefa.fonte
Eu também não sabia fazer isso até que pensei em usar PHP
array
. E tenho certeza de que essa é a maneira mais simples de gerar uma string ou número aleatório com array. O código:Você pode usar esta função assim
fonte
Semelhante à resposta de Brad Christie , mas usando
sha1
alroritmo para caracteres0-9a-zA-Z
e prefixado com um valor aleatório:Mas se você definiu caracteres (permitidos):
** ATUALIZAÇÃO **
Como Archimedix apontou, isso não garante o retorno da "menor possibilidade de duplicação", pois o número de combinações é baixo para o intervalo de caracteres fornecido. Você precisará aumentar o número de caracteres ou permitir caracteres extras (especiais) na string. A primeira solução seria preferível, eu acho, no seu caso.
fonte
time()
é até 1 milhão de vezes mais previsível do quemicrotime()
.$str
.˫§»⁋⅓
" simplesmente porque é mais seguro ... você aumenta sua chave de referência para 7 ou mais caracteres . (BTW: correção em meu comentário anterior, é 5x36 caracteres)funciona bem em PHP (php 5.4.4)
Demonstração ao vivo
fonte
Fonte: Função PHP que Gera Caracteres Aleatórios
Esta função PHP simples funcionou para mim:
Uso:
fonte
Aqui estão meus
random 5 cents
...A nova função do PHP
password_hash()
(*> = PHP 5.5) está fazendo o trabalho para a geração de conjuntos decentemente longos de letras maiúsculas e minúsculas e números.Dois concat. strings antes e depois da
password_hash
função $ random são adequadas para alteração.Os parâmetros para
$random()
* ($ a, $ b) são na verdadesubstr()
parâmetros. :)NOTA: isso não precisa ser uma função, pode ser uma variável normal também .. como um singleliner desagradável, como este:
fonte
fonte
Eu sempre uso isso:
Ao chamá-lo, define o comprimento da corda.
Você também pode alterar os caracteres possíveis na string
$a
.fonte