Niedziałający kod do "odgadywania hasła"

0

Witam
Piszę program który odgaduje ciąg znaków litera po literze i wyświetla go textboxie. Niestety napotkałem problem, mianowicie gdy klikam przycisk program wyświetla pojedynczą literę a nie całe hasło. Dodam także że do całej procedury używam bacgroundworkera. Po niżej zamieszczam kod. Z góry dziękuje za pomoc.

public Form1()
{
                   InitializeComponent();                   
            backgroundWorker1 = new BackgroundWorker();
            //     backgroundWorker1.WorkerReportsProgress = true; 
           backgroundWorker1.WorkerSupportsCancellation = true;
            backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
            backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted;        
            haslo = textBox2.Text;
}

    BackgroundWorker backgroundWorker1;
    int index = 0;
    int i = 0;
    string litery = "ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyz";
    string haslo;
  
    private void BackgroundWorker1_DoWork(object? sender, DoWorkEventArgs e)
        {
                for (int i = 0; i < litery.Length - 1; i++)
                {
                    if (!backgroundWorker1.CancellationPending)
                    {
                        try
                        {
                            this.Invoke((Action)delegate
                                        {       
                                            if (textBox1.Text=="")
                                            {
                                                index = 0;
                                            }
                                         
                                                while (litery[i] == textBox2.Text[index] && textBox1.Text.Length >= index - 1)                                       
                                                    {                                                                                                        
                                                        if (textBox1.Text.Length - 1 <= index)
                                                        {
                                                          
                                                            backgroundWorker1.CancelAsync();
                                                            index++;
                                                            textBox1.Text += litery[i].ToString();
                                                            textBox1.Select(index, textBox1.Text.Length - 1);

                                                            if (!backgroundWorker1.IsBusy)
                                                            {
                                                                backgroundWorker1.RunWorkerAsync();
                                                             
                                                            }
                                                        }
                                                     
                                                        else
                                                        {
                                                        //    break;
                                                    
                                                        }
                                                 }

                                            
                                        });
                        }
                        catch
                        {
                            break;
                        }
                    }                    
                } 
              
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            // Start odgadywania
            if (!backgroundWorker1.IsBusy)
            {
                backgroundWorker1.RunWorkerAsync();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {        
            // Zatrzymywanie odgadywania
            if (backgroundWorker1.IsBusy)
            {
                backgroundWorker1.CancelAsync();
                i = -1;
            }
        }

0

Opisz co dokładnie chcesz osiągnąć, jak ten program ma działać, najlepiej krok po kroku, na razie jest to średnio zrozumiałe.
Ten kod czyta się okropnie, poświęć kilka minut i usuń niepotrzebne komentarze i puste linie, pokaż jak deklarujesz i inicjalizujesz zmienne, nikt nie ma ochoty się tego domyślać.

0
Reinicke napisał(a):

Opisz co dokładnie chcesz osiągnąć, jak ten program ma działać, najlepiej krok po kroku, na razie jest to średnio zrozumiałe.
Ten kod czyta się okropnie, poświęć kilka minut i usuń niepotrzebne komentarze i puste linie, pokaż jak deklarujesz i inicjalizujesz zmienne, nikt nie ma ochoty się tego domyślać.

Chcę aby program po kliknięciu w przycisk porównał ciąg znaków z obydwu textboxów. Po sprawdzeniu czy znak jest w haśle na danym indeksie wyświetlił go w pierwszym textboxie i tak do końca długości hasła. Mam nadzieję że napisałem zrozumiale.

0

Podziel na male funkcji, inaczej tego nie przejdziesz.
Przecież to nawet nie ma prawa się skompilować, kompilator na 100% pokazuje gdzie jest problem.

0

Nie bardzo wiem jak miałbym to podzielić na funkcje. Co do kompilacji to program kompiluje się bez błędów.

0

Czyta się to fatalnie ale próbując jakoś się w tym cudzie połapać to chyba próbujesz wypisywać litery do text boxa tylko kiedy i jest mniejsze bądź równe index, a taka sytuacja zajdzie raz. I to by się zgadzało. Aczkolwiek jak koledzy wyżej wspomnieli - weź ten kod ogarnij trochę, posprzątaj, podziel sensownie bo oczy bolą

0
kuba7528 napisał(a):

Nie bardzo wiem jak miałbym to podzielić na funkcje. Co do kompilacji to program kompiluje się bez błędów.

while (litery[i] == textBox2.Text[index])
                                             textBox2.Text[index]&&textBox1.Text.Length>=index-1)
                                                    {
0

Niestety nie działa mi porównywanie znaków przepuszczone przez for. Jak mam porównać literę i jej pozycję w stringach ?

1

nie bardzo mogę załapać co chcesz osiągnąć.
Twój opis problemu jest niespójny z kodem, z którego to też nie można wywnioskować logiki.
Piszesz że porównujesz txtbox1 i txtbox2 a w txtbox1 chcesz coś wpisywać ? dla mnie bez sensu to brzmi.
A co z tym ciągiem literek,, po co on?
czy to czasami nie ma być coś w rodzaju gry w wisielca?
czy asynchroniczność ma jakiś ukryty sens, bo też tego nie łapię, po co?

0
kuba7528 napisał(a):

Chcę aby program po kliknięciu w przycisk porównał ciąg znaków z obydwu textboxów. Po sprawdzeniu czy znak jest w haśle na danym indeksie wyświetlił go w pierwszym textboxie i tak do końca długości hasła. Mam nadzieję że napisałem zrozumiale.

Ok, chyba załapałem o co Ci chodzi. Masz 2 textboxy(textBox1, textBox2), w obu jest wpisany tekst, po wciśnięciu button1 odpalasz backgroundWorker1, który porównuje tekst z obu textboxów i jeżeli jest taki sam to wpisuje go do textBox1(w którym ten tekst już jest wpisany). Żeby było "prościej" porównujesz litera po literze, używasz do tego globalnej zmiennej index i stringa litery z zapisanym całym alfabetem, dla każdej litery najpierw sprawdzasz czy występuje ona w alfabecie, jeżeli tak to szukasz jej w tekście w textBox2. Jeżeli znajdziesz to wpadasz w nieskończoną pętle(// break;) i dlatego masz przycisk button2, który zatrzymuje backgroundWorker1. Do tego są jeszcze globalne zmienne haslo i i, które nie są używane. I wywołanie rekurencyjne w 45 linii backgroundWorker1.RunWorkerAsync();, bo czemu nie. Dobrze zrozumiałem?

0

Ten ciąg znaków służy do porównywania w pętli z hasłem w textbox2.W grze w wisielca porównuje się jeden znak w dodatku nie musi o mieć zerowego indeksu. Ja chcę porównać od początku do końca hasła z literą z alfabetu i sprawdzić jej pozycję, czy zgadza się z pozycją hasła. Co do "hasla" i "i" to chciałem przypisać "haslo" do texbox2 a "i" wykorzystać jako indeks poszczególnej litery w tym texboxie2.

0
Reinicke napisał(a):
kuba7528 napisał(a):

Chcę aby program po kliknięciu w przycisk porównał ciąg znaków z obydwu textboxów. Po sprawdzeniu czy znak jest w haśle na danym indeksie wyświetlił go w pierwszym textboxie i tak do końca długości hasła. Mam nadzieję że napisałem zrozumiale.

Ok, chyba załapałem o co Ci chodzi. Masz 2 textboxy(textBox1, textBox2), w obu jest wpisany tekst, po wciśnięciu button1 odpalasz backgroundWorker1, który porównuje tekst z obu textboxów i jeżeli jest taki sam to wpisuje go do textBox1(w którym ten tekst już jest wpisany). Żeby było "prościej" porównujesz litera po literze, używasz do tego globalnej zmiennej index i stringa litery z zapisanym całym alfabetem, dla każdej litery najpierw sprawdzasz czy występuje ona w alfabecie, jeżeli tak to szukasz jej w tekście w textBox2. Jeżeli znajdziesz to wpadasz w nieskończoną pętle(// break;) i dlatego masz przycisk button2, który zatrzymuje backgroundWorker1. Do tego są jeszcze globalne zmienne haslo i i, które nie są używane. I wywołanie rekurencyjne w 45 linii backgroundWorker1.RunWorkerAsync();, bo czemu nie. Dobrze zrozumiałem?

Tak, dobrze kolega zrozumiał.
Ten ciąg znaków służy do porównywania w pętli z hasłem w textbox2.W grze w wisielca porównuje się jeden znak w dodatku nie musi o mieć zerowego indeksu. Ja chcę porównać od początku do końca hasła z literą z alfabetu i sprawdzić jej pozycję, czy zgadza się z pozycją hasła. Co do "hasla" i "i" to chciałem przypisać "haslo" do texbox2 a "i" wykorzystać jako indeks poszczególnej litery w tym texboxie2.

0

Źle się za to zabierasz, najpierw pomyśl jak to ma działać, ułóż sobie plan i dopiero wtedy zacznij kodować. Może zacznij od czegoś takiego:

  1. String do przechowywania odpowiedzi i label do wyświetlania "_ a _ _ _ a".
  2. String do przechowywania hasła, na start niech będzie hardcodowane
  3. TextBox do wpisywania odpowiedzi, najlepiej jakby można było wpisać do niego tylko jedną literę, powinien być czyszczony po każdym sprawdzeniu, żeby przygotować go do wpisania następnego znaku.
  4. Sprawdzanie najlepiej odpalać w TextChanged textBoxa, ewentualnie dodać button, jeżeli koniecznie chcesz mieć to na click.
  5. Nie potrzebujesz żadnego stringa z alfabetem, bakcgroundworkera ani rekurencji. Całe sprawdzanie można zrobić w jednej pętli, pętla leci po haśle, jeżeli znajdzie wpisaną literę to aktualizuje string z odpowiedzią i tekst labelki. Tyle wystarczy.
  6. Jak już wszystko będzie działało to można dodać losowe hasło, historię odpowiedzi, maksymalną ilość błędnych odpowiedzi itp.

Czyli na widoku wystarczy że będziesz miał jeden label, jeden textbox i ewentualnie jeden button. W code behind zmienne na hasło i odpowiedz oraz metoda do sprawdzania liter.

0
Reinicke napisał(a):

Źle się za to zabierasz, najpierw pomyśl jak to ma działać, ułóż sobie plan i dopiero wtedy zacznij kodować. Może zacznij od czegoś takiego:

Dokładnie.

Szycie algorytmów żywcem na GUI, nie wiadomo po co tryby asynchroniczne itd ...

@kuba7528:

Mocno uproszczona interpunkcja, i styl pisania w języku jakiego używasz, klon polskiego, nie podnosi twojego rankingu w oczach czytających.
Chaos w myślach, chaos w kodzie.
Tak, wiem, zaraz mnie zakrzyczą politycznie poprawni:"z dysgrafią można być dobrym programistą" ... no cóż, ten wątek mnie do tego nie przeokna.

0
private static int maxerror=7;
private string used="";
private string password="przeokna";
private string current=string('_',password.length);
private int errors=0;
public static enum state { NotLitter,Used,Good,Bad,Win,Loose; };

public string Current { get { return current; } }
public int Errors { get { return error; } }

public state checkLetter(char ch)
{
  if(!Char.IsDigit()) return state.NotLitter;
  ch=Char.ToLower(ch);
  if(used.Contains(ch)) return state.Used;
  used+=ch;
  string temp=current;
  for(int i=0;i<password.length;++i) if(password[i]==ch) temp[i]=ch;
  if(current!=temp) return (password==(current=temp)?state.Win:state.Good);
  else return (++errors>=maxerror?state.Loose:state.Bad);
}

Uwaga, pisano na kolanie.

0
ZrobieDobrze napisał(a):
Reinicke napisał(a):

Źle się za to zabierasz, najpierw pomyśl jak to ma działać, ułóż sobie plan i dopiero wtedy zacznij kodować. Może zacznij od czegoś takiego:

Dokładnie.

Szycie algorytmów żywcem na GUI, nie wiadomo po co tryby asynchroniczne itd ...

@kuba7528:

Mocno uproszczona interpunkcja, i styl pisania w języku jakiego używasz, klon polskiego, nie podnosi twojego rankingu w oczach czytających.
Chaos w myślach, chaos w kodzie.
Tak, wiem, zaraz mnie zakrzyczą politycznie poprawni:"z dysgrafią można być dobrym programistą" ... no cóż, ten wątek mnie do tego nie przeokna.

Ogarnąłem to. Niestety obsługuje tylko krótkie hasła (program przywiesza się przy dłuższych ) , gdy próbuje to wrzucić do bagroundworkera program nie działa. Podobno dysleksja to nie choroba, jednakże udało mi się coś napisać. Poniżej zamieszczam moje wypociny. Sprawdzę sobie także na spokoje kod od _13th_Dragon za który dziękuje.

  string haslo;
        public void Odgadnij_haslo()
        {
            haslo = textBox1.Text;
            //   odp = label1.Text;


            
                for (int i = 0; i <= haslo.Length - 1; i++)
                {
                    // for (char letter = 'a'; letter <= 'z'; letter++)
                    for (int x = char.MinValue; x <= char.MaxValue; x++)
                    {
                        char letter = Convert.ToChar(x);
                        textBox2.Text = letter.ToString();
                        if (haslo[i].ToString() == letter.ToString() && char.IsLetterOrDigit(letter))
                        {
                            label1.Text += textBox2.Text;

                        }


                        //    textBox2.Text = "";


                    }

                }
            
        }

0
kuba7528 napisał(a):

Ogarnąłem to.

Nadal jest totalny bezsens, może napisz komentarze do każdego wiersz co twoim zdaniem ten wiersz robi.

0

  string haslo; // deklaracja zmiennej haslo typu string
        public void Odgadnij_haslo()
        {
        // przypisanie hasla do texboxa
                     haslo = textBox1.Text;
       


            // przepuszczenie int'a przez długość hasła w celu późniejszego porównania znaku z jakimkolwiek znakiem z drugiej pętli  
                for (int i = 0; i <= haslo.Length - 1; i++)
                {
                   // tu może być problem bo wziąłem pewnie za duży zakres pod uwagę.
                   // pętla for przepuszczenie int'a przez wszystkie char'y.
                    for (int x = char.MinValue; x <= char.MaxValue; x++)
                    {
                    // deklaracja char i przypisanie do niego x
                        char letter = Convert.ToChar(x);
                        // wyświetlenie w texboxie char lettter
                        textBox2.Text = letter.ToString();

                        // sprawdzenie czy znak w haśle jest równy znakowi w z pętli for i czy jest on literą lub liczbą
                        if (haslo[i].ToString() == letter.ToString() && char.IsLetterOrDigit(letter))
                        {
                        // dodanie litery z texboxa2 do labela
                        // dodam że żadna litera nie wyświetla się w textbox2
                            label1.Text += textBox2.Text;

                        }


                 


                    }

                }
            
        }


Jeżeli moje komentarze są nie zrozumiałe to proszę o wyrozumiałość.

0
  • pętla for przepuszczenie int'a przez wszystkie char'y. po kiego ci ta druga pętla jak możesz pobrać znak z pozycji i (char letter = haslo[i])?
  • deklaracja char i przypisanie do niego x jak wyżej
  • wyświetlenie w texboxie char lettter po kiego? Właśnie użytkownik ma podać tą literę a nie ty wyświetlać.
  • ... i czy jest on literą lub liczbą człowieku, czy znasz różnicę pomiędzy liczbą a cyfrą? A co jeżeli to np znak zapytania?
  • sprawdzenie czy znak w haśle jest równy znakowi w z pętli to po kiego aby porównać znak ze znakiem najpierw konwertujesz je do napisu?
  • dodanie litery z texboxa2 do labela po prostu na końcu? niezależnie gdzie i ile razy wystąpiła? Czyli jak litera a wystąpi na 3-cim i 5-tym miejscu to zwyczajnie dodasz dwie a na początku?

Dodatkowo:
http://forum.4programmers.net/1101404
http://forum.4programmers.net/1208091

1

To nawet nie jest kwestia tego że nie wiesz jak coś zrobić, z Twojego kodu i wypowiedzi wynika że nie wiesz co chcesz zrobić. Może najpierw ułożymy konkretny scenariusz, krok po kroku:

  1. Wpisujemy literę w textBox1
  2. Wciskamy button1
  3. Jeżeli hasło zawiera podaną literę to program aktualizuje tekst w label1, odkrywając wpisaną literę na odpowiednich miejscach.
  4. Tekst w textBox1 jest czyszczony, powtarzamy kroki 1-4 aż nie odgadniemy całego hasła

Jak już pisałem, do samego sprawdzania podanej litery wystarczy Ci jedna pętla:

        string password = "haslo";
        StringBuilder resultSB = new StringBuilder("-----");

        public void Odgadnij_haslo(char letterToCheck)
        {
            for (int i = 0; i < password.Length; i++)
            {
                if (password[i] == letterToCheck)
                {
                    resultSB[i] = letterToCheck;
                }
            }
        }

StringBuilder zamiast string żeby móc łatwo podmieniać litery.
Na button click wywołujesz Odgadnij_haslo, aktualizujesz tekst w label1 używając resultSB.ToString() i na koniec czyścisz tekst w textBox1. Dodaj jeszcze zabezpieczenie przed pustym tekstem w textBox1, zmodyfikuj metodę Odgadnij_haslo żeby nie rozróżniała małych i wielkich liter i gotowe.

1
Reinicke napisał(a):

To nawet nie jest kwestia tego że nie wiesz jak coś zrobić, z Twojego kodu i wypowiedzi wynika że nie wiesz co chcesz zrobić.

Coś mi się wydaje że kolega kuba7258, wie co chce zrobić, tylko nie chce głośno powiedzieć.
Obstawiam że to ma być "mechanizm" Do łamania haseł
Ale to nie tędy droga i to nie ma sensu.
Lepiej hasło ukraść 😁

0
master_mix napisał(a):
Reinicke napisał(a):

To nawet nie jest kwestia tego że nie wiesz jak coś zrobić, z Twojego kodu i wypowiedzi wynika że nie wiesz co chcesz zrobić.

Coś mi się wydaje że kolega kuba7258, wie co chce zrobić, tylko nie chce głośno powiedzieć.
Obstawiam że to ma być "mechanizm" Do łamania haseł
Ale to nie tędy droga i to nie ma sensu.
Lepiej hasło ukraść 😁

Dokładnie tak. Kradzież hasła z niezaszyfrowanego stringa, ciekawe. To ma być prosty program do łamania hasła znak po znaku. Nie jestem jakimś tam zaawansowanym programistą żeby wiedzieć wszystko. Programowanie to jedynie moje hobby stąd też wynika kiepskiej jakości kod. Jeśli chodzi o samo podejście do programu to nie programuje zbyt często i być może stąd nie mam nawyku analizowania kodu punkt punkcie.

1
kuba7528 napisał(a):

... To ma być prosty program do łamania hasła znak po znaku ...

Naoglądałeś się kiepskich seriali? Tylko tam jakieś super sekretne urządzenie "lamie kod" znak po znaku.
Z tym że wszędzie tam gdzie jest potrzebny taki kod/hasło nie ma możliwości sprawdzenia czy znak na pozycji X to Y, więc takie buty tylko w kiepskich serialach.

0
_13th_Dragon napisał(a):
kuba7528 napisał(a):

... To ma być prosty program do łamania hasła znak po znaku ...

Naoglądałeś się kiepskich seriali? Tylko tam jakieś super sekretne urządzenie "lamie kod" znak po znaku.
Z tym że wszędzie tam gdzie jest potrzebny taki kod/hasło nie ma możliwości sprawdzenia czy znak na pozycji X to Y, więc takie buty tylko w kiepskich serialach.

Myślałem że to prosta sprawa nie używając szyfrowania. Dlatego na początku chciałem spróbować na haśle jawnym.

1 użytkowników online, w tym zalogowanych: 0, gości: 1