Jump to content
karina pereira refacho

Combinação letra e numeros com apenas uma repetição

Recommended Posts

Pessoal estou tentando fazer todas as combinação de 32 caracteres letras e numeros com apenas uma repetição exemplo abaixo

resultado 

c4ca4238a0b923820dca509a6f758998

c4ca4238a0b923820dca509a6f759099

c4ca4238a0b923820dca509a6f759100

c4ca4238a0b923820dca509a6f759101

nesse exemplo acima gera no maximo uma repetição fiz um codigo que vou postar abaixo mas esta dando erro eu entendo muito pouco de php ainda estou aprendendo

<?php
 
function gerarCobinacao($tam){
    $seed = str_split('abcdef0123456789');
    shuffle($seed);
    $rand = '';
    foreach (array_rand($seed, $tam) as $k) 
      $rand .= $seed[$k];
 
    return $rand;
 }
 
print gerarCobinacao(32);

desde já agradeço a atenção de todos obrigada, no aguardo

Share this post


Link to post
Share on other sites

aparece esse erro WARNING array_rand(): Second argument has to be between 1 and the number of elements in the array on line number 7

testei no site phptester alem desse erro ele so esta imprimindo uma linha, obrigada pela atenção tenha uma ótima semana 

Share this post


Link to post
Share on other sites

Não sei se é o resultado que espera, mas recentemente criei essa classe:

CreateCode.php

Spoiler

<?php

/**
 * Description of CreateCode
 *
 * @author Spell Master
 */
class CreateCode {

    private $lengths;
    private $chars;
    private $code;

    /**
     * Cria um código de string aleatório
     * @param {INT} $len : Quandidade de caracteres no código, se não informado o valor será 5
     * @return {STR} Código alfabético com quantidade de caracteres informados pelo $len
     */
    public function strCode($len = null) {
        $this->lengths = (isset($len) ? (int) $len : 5);
        $this->chars = 'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVxXyYwWzZ';
        $this->setCode();
        return ($this->code);
    }

    /**
     * Cria um código de string aleatório
     * @param {INT} $len : Quandidade de caracteres no código, se não informado o valor será 5
     * @return {STR} Código numérico com quantidade de caracteres informados pelo $len
     */
    public function intCode($len = null) {
        $this->lengths = (isset($len) ? (int) $len : 5);
        $this->chars = '0123456789';
        $this->setCode();
        return ($this->code);
    }

    /**
     * Cria um código de string aleatório
     * @param {INT} $len : Quandidade de caracteres no código, se não informado o valor será 10
     * @return {STR} Código numérico e alfabético misturados com quantidade de caracteres informados pelo $len
     */
    public function defCode($len = null) {
        $this->lengths = (isset($len) ? (int) $len : 10);
        $this->chars = '0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVxXyYwWzZ0123456789';
        $this->setCode();
        return ($this->code);
    }

    /**
     * Cria o código baseado nas informações dos métodos públicos
     */
    private function setCode() {
        $this->code = "";
        $chars = str_split($this->chars);
        for ($i = 0; $i < $this->lengths; $i++) {
            $this->code .= $chars[array_rand($chars)];
        }
    }

}

 

 

Exemplo de uso:

<?php
require('CreateCode.php');

$codigo = new CreateCode();

echo $codigo->strCode(); // Isso vai gerar um código aleatório de 5 letras
echo ("<hr>");

echo $codigo->intCode(); // Isso vai gerar um código aleatório de 5 numeros
echo ("<hr>");

echo $codigo->defCode(); // Isso vai gerar um código aleatório de 10 caracteres que podem ser numeros ou letras misturados
echo ("<hr>");

// Criando um código que nunca vai se repetir
$unico = $codigo->defCode(32).time();
echo $unico;

Leia a descrição de cada método da classe para melhor entendimento.

Obs.: Se vai dar Ctrl+C e Ctrl+V. Cuidado pois esse editor aqui do fórum insere caraceteres não legíveis, o que vai gerar erro no arquivo que colar o texto

 

Seria isso que procura?

Share this post


Link to post
Share on other sites

Obrigado amigo pela resposta mas não e isso eu queria que o script me gerasse todas as combinações com apenas no maximo uma repetição em cada linha exemplo digamos que a primeira linha gerada seja essa abaixo

c4ca4238a0b923820dca509a6f758198

ai o sistema ia gerando em sequencia tipo assim

c4ca4238a0b923820dca509a6f758198

c4ca4238a0b923820dca509a6f758199

c4ca4238a0b923820dca509a6f758200

c4ca4238a0b923820dca509a6f758201

assim por diante detalhe e que no final repetil 2 caracteres teria que limitar a apenas dois eu iria despejar todas as sequencias em um arquivo txt o script para o txt eu já tenho só não tenho o script gera as combinações, antes que cometem isso será testado em uma workstation com 32 nucleos e 2048GB de memoria RAM

OBRIGADA PELA AJUDA ÓTIMO FINAL DE SEMANA

Share this post


Link to post
Share on other sites

Nesse caso que percebo que deve-se gerar uma sequência, então porque não gerar um loop e ir criando a sequência?

Não sei qual o critério para geração da base, aqui vou supor que seja simplesmente uma string única.

Então se temos: c4ca4238a0b923820dca509a6f758198

A base - c4ca4238a0b923820dca509a6f

O código - 758198

Sendo assim a próxima string gerada deve ser: c4ca4238a0b923820dca509a6f758199

Que é 758198 + 1

Mas deve terminar as sequências quando chegar ao suposto 758201

Então vou criar uma sequencia que vai começar em 758198 e terminar em 758201, pós então irei inserir as sequencias em um arquivo de texto.

<?php
$base = 'c4ca4238a0b923820dca509a6f';
$inicio = 758198;
$final = 758201;
$resultado = "{$base}{$inicio}\n";

while ($inicio != $final) {
    $inicio++;
    $resultado .= "{$base}{$inicio}\n";
}

$txt = fopen(__DIR__ . '/arquivo.txt', 'a');
fwrite($txt, $resultado);
fclose($txt);

O que vai gerar a seguinte coisa no arquivo.txt

c4ca4238a0b923820dca509a6f758198
c4ca4238a0b923820dca509a6f758199
c4ca4238a0b923820dca509a6f758200
c4ca4238a0b923820dca509a6f758201

 

Seria mais ou menis isso?

Porque não entendi o que quis dizer com isso:

13 horas atrás, karina pereira refacho disse:

detalhe e que no final repetil 2 caracteres teria que limitar a apenas dois

 

Share this post


Link to post
Share on other sites

obrigada pela ajuda estamos chegando lá, nesse seu exemplo acima preciso que as combinaçoes geradas inclua letras e numeros, eu preciso gerar todas as combinaçoes de abcdef0123456789 com 32 caracteres, sendo que só tenha uma repetição nós 32  caracteres,  um exemplo digamos que a primeira linha seja gerado assim 

c4ca4238a0b923820dca509a6f758200

c4ca4238a0b923820dca509a6f758201

se observar repetiu 2 caracteres que foi os 00 no final, em todas as outras sequencias quando aparecer a combinação com mais de duas repetiçoes pular e não salvar, digamos que ao continuar gerar todas as combinações ele gera uma combinação assim

 ccca4238a0b993820dca509a6f758200

se observar nesse exemplo acima teve 3 repetições no começo onde tem ccc no meio onde tem 99 e no final onde tem 00 o script deveria pular e ir na próxima limitando em apenas uma repetição de 2 caracteres. igual a esse exemplo abaixo

c4ca4238a0b923820dca509a6f758998

c4ca4238a0b923820dca509a6f759099

 

precisso que saia assim em toda a sequencia, se observarmos no final onde estava 8998 a próxima sequencia em vez de ele salvar 8999 ele pulou e salvou com 9099 pois aqui limitou a 2 caracteres preciso gerar todas as combinações letra e numeros com essa limitação em todo os 32 caracteres gerados incluindo letras e numeros, muito obrigada pela ajuda de todos ótimo final de semana a todos

Share this post


Link to post
Share on other sites

Vish.... Complicado

O problema da questão é que de "0 a 9" e de "A até o Z" temos o total de 36 caracteres.

Então gerar um código "SEM REPETIR" caracteres para chegar ao total de 32 é uma tarefa além de complicada é exaustiva para um sistema executar.

 

Bem eu consegui fazer da seguinte forma:

Usei a mesma lógica para criar um código de com letras e números aleatoriamente, porém nesse termo podemos ter a repetição de caracteres, então a alternativa que tomei foi contar qualquer ocorrência duplicada acima de 1 caractere, ou seja sempre estarei permitindo até 2 caracteres iguais em sequencia na string Expl. "AAA" (Não pode) / "AA" (Pode) 

Então o que fazer? Se houver mais de 1 ocorrência duplicada gero novamente o código até que ele se enquadre nos critérios.

Porém só gero esse código aleatório com 30 chars porque deixo os 2 últimos caracteres para serem gerados como inteiros por auto-increment.

 

Tive de usar orientação a objeto porque tive de comunicar os mesmos dados entre duas funções distintas, então assim ficou a classe:

Spoiler

<?php
class CodeMutable {

    private $code;
    private $arrChar;

    /*
     * Cria uma string de letras e números aleatórios
     */
    private function newCode() {
        $this->arrChar = str_split('0123456789abcdefghijklmnopqrstuvxywz'); // Total 36 caracteres
        $this->code = "";
        for ($i = 0; $i < 30; $i++) {
            $this->code .= $this->arrChar[array_rand($this->arrChar)];
        }
    }

    /*
     * O pulo do gato está aqui!
     * Primeiro chamo o método para criar o código, ao qual pode ter caracteres repetitiveis.
     * Mas temos o array com todos os chars e a string criada pelo método
     * Então percorremos a string em busca de ocorrencias duplicadas da array
     * Se existirem mandamos criar outro código.
     * Esse processo fica se repetindo até que não chegue a existir mais duplicações
     */
    private function filterCode() {
        $this->newCode();
        foreach ($this->arrChar as $len) {
            if (substr_count($this->code, $len) > 1) {
                $this->newCode();
            }
        }
    }
    
    /*
     * Executa os métodos e retorna o resultado
     */
    public function getCode() {
        $this->filterCode();
        return $this->code;
    }

}

 

 

Sendo assim continuando o meu raciocínio anterior gero o código final usando um loop:

Spoiler

<?php
require ('CodeMutable.php');
$codigo = new CodeMutable();
$base = $codigo->getCode();

$inicio = 10;
$final = 20;
$resultado = "{$base}{$inicio}<br>";

while ($inicio != $final) {
    $inicio++;
    $resultado .= "{$base}{$inicio}<br>";
}

echo $resultado;

 

 

No que gera códigos como esse:

Spoiler

48n7og61nhtjqei1nm0kmlsx2kvqk810
48n7og61nhtjqei1nm0kmlsx2kvqk811
48n7og61nhtjqei1nm0kmlsx2kvqk812
48n7og61nhtjqei1nm0kmlsx2kvqk813
48n7og61nhtjqei1nm0kmlsx2kvqk814
48n7og61nhtjqei1nm0kmlsx2kvqk815
48n7og61nhtjqei1nm0kmlsx2kvqk816
48n7og61nhtjqei1nm0kmlsx2kvqk817
48n7og61nhtjqei1nm0kmlsx2kvqk818
48n7og61nhtjqei1nm0kmlsx2kvqk819
48n7og61nhtjqei1nm0kmlsx2kvqk820

 

Fiz o teste dezenas de vezes e nenhuma vez aconteceu de coexistir 3 caracteres iguais, mesmo que existe uma margem disso acontecer nos 3 últimos.

 

 

@Matheus Tavares Dar um help aqui porque minhas idéias acabaram.

Share this post


Link to post
Share on other sites

Obrigada  estamos quase lá fiz uma pequena modificação em seu script ficou assim

<?php
class CodeMutable {

    private $code;
    private $arrChar;

    /*
     * Cria uma string de letras e números aleatórios
     */
    private function newCode() {
        $this->arrChar = str_split('0123456789abcdef'); // Total 36 caracteres
        $this->code = "";
        for ($i = 0; $i < 32; $i++) {
            $this->code .= $this->arrChar[array_rand($this->arrChar)];
        }
    }

    /*
     * O pulo do gato está aqui!
     * Primeiro chamo o método para criar o código, ao qual pode ter caracteres repetitiveis.
     * Mas temos o array com todos os chars e a string criada pelo método
     * Então percorremos a string em busca de ocorrencias duplicadas da array
     * Se existirem mandamos criar outro código.
     * Esse processo fica se repetindo até que não chegue a existir mais duplicações
     */
    private function filterCode() {
        $this->newCode();
        foreach ($this->arrChar as $len) {
            if (substr_count($this->code, $len) > 1) {
                $this->newCode();
            }
        }
    }
    
    /*
     * Executa os métodos e retorna o resultado
     */
    public function getCode() {
        $this->filterCode();
        return $this->code;
    }

}
 ('CodeMutable.php');
$codigo = new CodeMutable();
$base = $codigo->getCode();

$inicio = '';
$resultado = "{$base}{$inicio}<br>";



echo $resultado;

se executar esse script vai gerar uma linha com 32 caracteres, preciso de todas as combinações com apenas uma repetição se não for possível gerar com apenas uma repetição como faço para gerar todas as combinações e despejar no txt lembrando que irei fazer o teste em um pc muito bom na empresa workstation com 32 nucleos e 2048MB de ram   obrigado pela atenção.

Share this post


Link to post
Share on other sites

Pesquisando na internet achei esse array abaixo

array_merge ( range ( 'a' , 'f' ) , range ( 0 , 9 ) ) ;

agora não sei como eu faço para gerar todas as combinações desse array com 32 caracteres, limitando apenas a uma repetição

exemplo no codigo gerado não pode ter repetições maior que dois caracteres tipo aaa ou eeee etc

 

sei muito pouco sobre php se alguém puder me dar uma luz ficarei muito agradecida obrigada

Share this post


Link to post
Share on other sites

Olá pessoal. Tudo bem?

 

Bom... se os caracteres são hexadecimais (a-f e 0-9) e com um comprimento de 32 caracteres, pelo que entendi estamos lidando com hashes MD5.

 

O problema é o seguinte. Quantas permutações possíveis temos baseado nesse range?

Como o MD5 é um algoritmo hash de 128 bits a quantidade de possibilidades únicas é calculada por 2 ** 128. O resultado disso são "meros" 340,282,366,920,938,463,463,374,607,431,768,211,456.

Claro, se formos remover todas as strings com mais de um trio duplicado (como "aaa" ou "00000"), teremos uma boa redução desse número.

 

Onde quero chegar? Bom, vocês já devem saber... isso é custoso. Muito custoso. O PHP não deveria nem ser cogitado para solucionar esse problema. Esse tipo de cálculo geralmente é feito pela GPU hoje em dia.

 

Existem rainbow tables (tabelas prontas com muitas possibilidades de hashes MD5)... mas isso pode superar TBs (sim, terabytes) de dados. Vejam exemplos:

https://project-rainbowcrack.com/table.htm

http://project-rainbowcrack.com/

http://rainbow-tables.com/

 

Minha sugestão é que no mínimo esqueça o PHP e tente solucionar isso com C. A sintaxe nem é tão diferente e a quantidade de código não é tão grande, mas a performance é bem diferente.

 

Sobre o código, minha sugestão é atomizar ao máximo. Essa tarefa não precisa ser feita por apenas um algoritmo. Você pode ter centenas de instâncias (ou até máquinas) rodando, cada uma cumprindo uma função. Exemplo: do 0 ao f temos 16 caracteres, correto? Então você poderia ter 16 arquivos resultantes, cada um começando com um dos caracteres e cada um sendo gerado por um programa diferente (porém agora expanda esse exemplo e crie muito mais ramificações. 16 era apenas um exemplo).

 

Espero ter ajudado. Boa sorte :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By Gabrielbdec
      Boa noite,
       
      Eu precisava de uma ajuda em encontrar uma lógica para resolver meu problema. Tenho certeza que qualquer programação seria possível.
       
       
      Eu tenho 5 espaços.
       
      _ _ _ _ _
       
      Cada um desses espaços vai um número de 0 a X. Esse X é dado pelo usuário (inteiro). O problema é que tem de ser feita uma distribuição desses espaços em X. Ou seja, a soma de todos os espaços tem de ser exatamente X.
       
      Exemplo:
       
      1 -> 1000/01000/00100/00010/00001
      2 -> 2000/11000/10100/10010/10001/02000/01100/01010/01001/00200/00110/00101/00020/00011/00002
       
      E assim se segue.
       
      Eu coloquei um contador que rodava como se fosse um relógio digital e ele só fazia a minha função o momento que ele somava e conseguia o X, como segue abaixo:
      Do While t <> (x + 1) v = v + 1 If v = (x + 1) Then m = m + 1 v = 0 End If If m = (x + 1) Then l = l + 1 m = 0 v = 0 End If If l = (x + 1) Then e = e + 1 l = 0 m = 0 v = 0 End If If e = (x + 1) Then t = t + 1 e = 0 l = 0 m = 0 v = 0 End If If t + e + l + m + v = x Then 'Função... End If Loop O problema, é que quando eu colocava um X como 20 já demorava 2 segundos para me retornar o valor, cada número que aumento em x cresce exponencialmente a quantidade de cálculos e, consequentemente, o tempo. Em força bruta (como estou fazendo) não está me ajudando. Tinha o mesmo problema para 2 espaços e era super tranquilo distribuir os dados, para 3 foi um pouco mais difícil, mas consegui, agora, para 5, não consegui achar um padrão de mudança para cada algarismo.
       
      Alguém teria alguma forma de me ajudar? Alguma dica de como buscar diminuir a quantidade de cálculos?
       
       
      Muito obrigado de qualquer modo, att.
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.