Quebra de senha, código simples (em JAVA)

Eu não sei se pode pôr simplesmente o código inteiro aqui, então pus no pastebin.
Eu estou querendo receber uma senha de até 4 dígitos, e depois fazer uma verificação até chegar na senha que foi posta. Fiz um loop em for, quando ele chegasse na senha correta era pra parar de tentar achar a senha e mostrar “senha correta”, mas não aparece e fica eternamente tentando achar a senha.

https://pastebin.com/Pd3ZETFx

– Sou novato em programação ^^

Quando encontrar a senha você tem que interromper o loop. Nesse caso, você pode usar uma flag ou simplesmente usar o break. Mas pelo que vi no seu código, o laço prevê até 10.000 repetições (o que por sinal é um valor muito alto, muito embora esteja de acordo com o PFC - 10^4), não havendo nenhuma condição de parada para o for. Com efeito, no melhor dos casos o for terá 1 iteração e no pior 10.000 iterações. O mais correto era código testar para os conhecidos e não para as possibilidades. Explico: em vez do código buscar por possibilidades (ir gerando números) e ver se dá ‘match’, ou seja se há correspondência, ele deveria testar se uma determina senha tem correspondente em um universo de senhas finito (sendo esse universo o reduzido possível). É como se as senhas registradas estivessem em um BD ou em uma lista, bastando verificar se a senha informada tem algum correspondente no BD ou na lista de senhas cadastradas.
Contudo, você pode transpor a condição do else if para o for, por exemplo:

while(correta != true) {
	if(tentativa.equals(mask)) {               
		System.out.println("Senha correta");
		JOptionPane.showMessageDialog(null, "senha correta");
		correta = true;
	}else {
		for(int i = 0; i < 10000; i++) {
			tentativa.append(df.format(i));
			System.out.println(tentativa);
			tentativa.append("\n");
			
			if(tentativa == mask){
				correta = true;
				i = 10000; //interrompe o laço
			}
		}
	}
}

eu copiei o que você fez, e não interrompeu o for :confused:
e poderia me dizer como eu faria dessa forma de buscar nas senhas registradas?

Agora que eu prestei atenção… Tu está apensando a tentativa a cada iteração do for. Veja o que isso gera:

Iteração 1: tentativa 0000\n
Iteração 2: 0000\n + tentativa que resulta em 0000\n0001\n
iteração n: […]
Logo, nunca haverá correspondência.
Uma forma de resolver:

import java.text.DecimalFormat;
import javax.swing.JOptionPane;
 
public class Desafio08 {
   
    public static void main(String[] args) {
       
        StringBuffer mask = new StringBuffer();
        DecimalFormat df = new DecimalFormat("0000");
        int senha = Integer.parseInt(JOptionPane.showInputDialog("Digite uma senha númerica de 4 dígitos"));
        mask.append(df.format(senha));
        boolean correta = false;
        StringBuffer tentativa = new StringBuffer();
       
        System.out.println("M: " + mask);
       
       
        JOptionPane.showMessageDialog(null, mask);
       
        while(correta != true) {
            if(tentativa.equals(mask)) {               
                System.out.println("Senha correta");
                JOptionPane.showMessageDialog(null, "senha correta");
                correta = true;
            }else{
                for (int i = 0; i < 10000; i++) {
					//tentativa.append(df.format(i));
					/*
					* Em vez de apensar, eu gero um novo StringBuffer
					*/
					tentativa = new StringBuffer(df.format(i)); 
                    System.out.println(tentativa);
					/*
					* Se você colocar uma quebra de linha no final, nunca irá dar match
					*/
                    //tentativa.append("\n");
					System.out.println("\n");
					
					/*
					* O método equals no StringBuffer é u método herdado de Object, mas não o subscreve. Portanto, 
					compara objetos. Nesse caso, queremos comparar as Strings, então...
					*/
					if(tentativa.toString().equals(mask.toString())){
						correta = true;
						System.out.println("Match!" + "A senha " 
							+ mask + " corresponde a tentativa: " + tentativa + ".");
						i = 10000;
					}
                }
            }
        }
    }
}

Teste:

image

Devo lembrar que, se por exemplo a senha for 7532, então haverá 7.532 iterações. Logo a melhor maneira de resolver isso, seria listar as senhas aceitas e testar se a senha digitada bate.

Obrigado! Mais uma coisa, se não pelo for, de que outra maneira eu poderia fazer isso dentro do while? Talvez seria mais certo sem o for.

Você poderia usar só aquele while

Eu percebi que esse While está sendo totalmente inútil, eu tirei tudo do while e deixei só o for, e funcionou normalmente. Eu queria saber como eu poderia fazer essas tentativas até acertar sem utilizar o for, e utilizar o while

Exemplo:

import java.text.DecimalFormat;
import javax.swing.JOptionPane;
 
public class Desafio08B {
   
    public static void main(String[] args) {
		final int MAX = 10000;
		int j = 1;
        StringBuffer mask = new StringBuffer();
        DecimalFormat df = new DecimalFormat("0000");
        int senha = Integer.parseInt(JOptionPane.showInputDialog("Digite uma senha númerica de 4 dígitos"));
        mask.append(df.format(senha));
        boolean correta = false;
        StringBuffer tentativa = new StringBuffer();
       
        System.out.println("M: " + mask);
       
       
        JOptionPane.showMessageDialog(null, mask);
       
        while(correta != true && j < MAX) {
            if(tentativa.equals(mask)) {               
                System.out.println("Senha correta");
                JOptionPane.showMessageDialog(null, "senha correta");
                correta = true;
            }else{
				tentativa = new StringBuffer(df.format(j++));
				System.out.println(tentativa);
				System.out.println("\n");

				if(tentativa.toString().equals(mask.toString())){
					correta = true;
					System.out.println("Match!" + " A senha " 
						+ mask + " corresponde a tentativa: " + tentativa + ".");
				}
            }
        }
    }
}

Rodando…


image

1 curtida

Muito obrigado!!