Prosty generator haseł

0

W WPF stworzyłem program, który pobiera wartość z jednej rubryki i ustawia na jej podstawie długość losowo wygenerowanego ciągu znaków. Niestety, nie wiedzieć czemu losowość jest mało losowa :P . Np. dla długości 7 output przy kolejnych kliknięciach przycisku generującego prezentuje się następująco:

11HH33J
F11HHH3
DD000FF
44KKK66
T@@@VVV

Kod(C#):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace KeyGen
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
       int passwordLength=0;


        public MainWindow()
        {
            InitializeComponent();
        }

       

        private void generateButton_Click(object sender, RoutedEventArgs e)
        {
            string temp;

            temp = textBox2.Text;
            
            if(textBox2.Text != "")
            passwordLength = Int32.Parse(temp);

            finalTextBox.Text = "";
           
            for(int i=0; i<passwordLength ; i++)
            finalTextBox.Text +=GetRandomChar() ;
        }

        private void textBox2_TextChanged(object sender, TextChangedEventArgs e)
        {
            


        }
        
        private char GetRandomChar()
        {
            char randomChar;
            int counter=0;

           Random x;
           x = new Random(System.DateTime.Now.Millisecond+counter);

           randomChar=(char) x.Next(45, 88);

           counter += 10000;
            
           return randomChar;
        }


      
    }
}
 

Przecież w funkcji Random przy każdym wywołaniu funkcji ustawiane jest inne nasienie...

1
           Random x;
           x = new Random(System.DateTime.Now.Millisecond+counter);

A czy nie wystarczy raz tego inicjować?

0

Wystarczy, ale to i tak nic nie zmienia jeśli chodzi o działanie programu.

1

Pytanie laika: czemu za każdym razem inicjalizujecie Random? myślałem że starczy Random.Next

1
kutacz napisał(a)

private char GetRandomChar()
{
char randomChar;
int counter=0;

       Random x;
       x = new Random(System.DateTime.Now.Millisecond+counter);

       randomChar=(char) x.Next(45, 88);

       counter += 10000;
        
       return randomChar;
    }
> 
> Przecież w funkcji Random przy każdym wywołaniu funkcji ustawiane jest inne nasienie...

Cóż nie znam C# i .NET, ale w Delphi najpierw uruchamia się `randomize;` a dopiero potem wywołuje się funkcję random.
Poza tym nie wiem co Ci da zwiększenie licznika **counter += 10000;** na końcu funkcji skoro jest to zmianna lokalna (tak mi się wydaje, ale jak wspomniałem nie znam C#)

Po tym uproszczeniu za zmienność ma wpływ tylko pętla **for**. nie wiem zupełnie co oznacza **randomChar=(char) x.Next(45, 88);** więc, być może moje przypuszczenia i wnioski są błędne.
0

Ja zawsze programowałem w C/C++, w tym niby rozwinięciu tych języków dodając

 static int counter=0; 

Wyskakuje błąd "The modifier static is invalid"

0

Wygląda na to że w C# nie można ustawiać zmiennych statycznych wewnątrz funkcji <facepalm> . Teraz mam licznik w klasie main, strasznie kretyństko to wygląda ale przynajmniej program działa jak należy :-)

2

Wygląda na to że w C# nie można ustawiać zmiennych statycznych wewnątrz funkcji

:| Wielki facepalm, do tego właśnie są pola klasy żeby przechowywać w nich zmienne lokalne dla klasy.

A jeszcze większy facepalm to tworzenie obiektu Random za każdym razem.

Mówisz że pisałeś w C++ więc przerobię to na C++:

char GetRandomChar()
        {
            char randomChar;
            int counter=0;
 
           srand(GetTime()+counter); // o_o
 
           randomChar=(char) rand()%43 + 45;
 
           counter += 10000; // o_o
 
           return randomChar;
        }
0
Tezcatlipoca napisał(a)

:| Wielki facepalm, do tego właśnie są pola klasy żeby przechowywać w nich zmienne lokalne dla klasy.

No niby tak, ale z drugiej strony po co pchać licznik jednej jedynej funkcji do całej klasy? Jaki mógł być cel blokowania zmiennych statycznych wewnątrz funkcji?

3

Tylko że w C++ znalazło się to w ramach kompatybilności wstecznej z C, a w C to miało wielki sens. Brak jakiejkolwiek modułowości, częsta konieczność stosowania globalnych zmiennych - w takich warunkach możliwość oszczędzenia zakresu globalnego przed zmienną występującą tylko w jednej funkcji mogła być zbawieniem.

Object-Oriented way robienia czegoś takiego wyglądałby tak:

class UniqueRand
{
    int counter = 0;
    Random r = new Random();

    public int Next()
    {
        counter++;
        return r.Next() + couner;
    }
}

Wtedy używając klasy UniqueRand osiągasz to samo u żadna klasa nie jest zaśmiecona niepotrzebnym jej licznikiem.
Ale i tak nie ma potrzeby pisania czegoś takiego - wystarczy tworzyć obiekt Random tylko raz.

0
ubuntuser napisał(a)

Pytanie laika: czemu za każdym razem inicjalizujecie Random? myślałem że starczy Random.Next

Pewno dlatego, że ktoś się rzucił na C# jak szczerbaty na suchara, bez przeczytania dokumentacji i zamiast jak człowiek raz utworzyć obiekt klasy Random, a potem wywoływać na nim Next do woli, cuduje z jakimiś cudacznymi "counterami".

kutacz napisał(a)

Wygląda na to że w C# nie można ustawiać zmiennych statycznych wewnątrz funkcji <facepalm> .

Owszem, C# jest wolny od tego typu gównianych rozwiązań.
Wygląda na to, że w samochodzie nie trzeba pedałować, żeby jechać <facepalm>.

No niby tak, ale z drugiej strony po co pchać licznik jednej jedynej funkcji do całej klasy?

A co, jeśli funkcji jest więcej niż jedna?

Jaki mógł być cel blokowania zmiennych statycznych wewnątrz funkcji?

Uproszczenie języka tak, żeby nie wyglądał jak jamnik z przybitymi czterema deskami pod wodą?

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