Es geht um einen Passwortgenerator der pro Runde (wird als Parameter bei GetNewPassword() definiert) 4 Zufallscharacters aussuchen soll. Einen Gross- und einen Kleinbuchstaben, ein Sonderzeichen und eine Zahl. Bei mehreren Runden werden die Blöcke zusammengefügt und ergeben ein Passwort. Demnach ist ein Passwort mit 1 Runde 4 Zeichen lang, 2 Runden sind 8 Zeichen, 3 Runden sind 12 Zeichen usw.
public partial class Test : System.Web.UI.Page
{
/// <summary>
/// This Hashtable will contain different <c>char</c> arrays, filled with allowed characters
/// </summary>
private Hashtable charactersHashtable;
protected void Page_Load(object sender, EventArgs e)
{
charactersHashtable = new Hashtable();
charactersHashtable.Add(0, "!#$%_=+".ToCharArray());
charactersHashtable.Add(1, "0123456789".ToCharArray());
charactersHashtable.Add(2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray());
charactersHashtable.Add(3, "abcdefghijklmnopqrstuvwxyz".ToCharArray());
}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox1.Text = GetNewPassword(3);
}
private string GetRandomChar(int hashtableKey)
{
char[] c = (char[])charactersHashtable[hashtableKey];
Random rand = new Random();
int lower = (int)c.GetLowerBound(0);
//Response.Write(lower + ",");
int upper = (int)c.GetUpperBound(0);
//Response.Write(upper + ",");
int randomCharPosition = rand.Next(lower, upper);
//Response.Write("[<strong>" + randomCharPosition + "</strong>],");
return c[randomCharPosition].ToString();
}
/// <summary>
/// Gets the new password.
/// </summary>
/// <param name="passwordStrength">Number of rounds, in other words the password strength. Every round creates a block of 4 index keys for the hashtable</param>
/// <returns>The new generated password</returns>
public string GetNewPassword(int passwordStrength)
{
StringBuilder pwdBuffer = new StringBuilder();
Queue keysQueue = new Queue();
Random rand = new Random();
for (int i = 0; i < passwordStrength; i++)
{
// Queue object will be created every round depending on passwordStrength
Queue rounds = new Queue();
for (int ii = 0; ii < 4; ii++)
{
int current = rand.Next(0, 4);
if (rounds.Contains(current))
{
ii--;
}
else
{
rounds.Enqueue(current);
keysQueue.Enqueue(current);
}
}
}
int count = keysQueue.Count;
for (int i = 0; i < count; i++)
{
int hashtableKey = Convert.ToInt32(keysQueue.Dequeue());
string randomChar = GetRandomChar(hashtableKey);
//**********************
// Wenn ich hier einen Breakpoint setze und debugge, funktioniert Random tadellos
//**********************
pwdBuffer.Append(randomChar);
}
//**********************
// Wenn ich hier einen Breakpoint setze und debugge, generiert Random 4 Zufallszahlen, aber wiederholt diese dann jede Runde.
// Also wenn ich ein Passwort mit Stärke 3 generiere (siehe Button1_Click()) kriege ich 4 Zufallszahlen, 3 mal wiederholt.
//**********************
return pwdBuffer.ToString();
}
}
Am Schluss von GetNewPassword() steht in Kommentaren, was schief läuft. Es ist echt seltsam. Der einzige Unterschied bei den Breakpoints ist, dass man beim oberen Breakpoint jeden einzelnen Aufruf von GetRandomChar() mitverfolgen kann und beim unteren nicht. Zurückgeben das Ergebnis sollte aber gleich aussehen. Ich bin echt am Ende meines Lateins.
Hallo epic_fail.
Du darfst Random nicht immer wieder neu erzeugen, sondern du musst eine Instanz halten.
Gruss
Friedel
Ohne Ziel ist auch der Weg egal.
Random berechnet Zufallszahlen (Pseudozufallszahlen) von einem Startwert (Seed) aus. Gibts du bei der Instanzierung einen anderen Seed an, bekommst du auch unterschiedliche Zufallszahlen. Standard Seed ist beispielsweise die aktuelle zeit.
PS: auch gut als Seed zu gebrauchen sind Guids:
Random rnd = new Random(Guid.NewGuid().GetHashCode());
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
Ich muss einen Start und Endwert angeben. Deshalb übergebe ich der Next() Methode den Lower- bzw. UpperBound eines arrays.
Was ich aber nicht verstehe: Warum wurde beim Debuggen trotzdem das richtige Ergebnis erstellt? Ist das ein Bug von VS? Wenn ich nun die Lösung so anschaue hätte ich sogar ein Compilerfehler erwartet...
Hallo epic_fail
Standardmässig ist der Seed AFAIK von der Uhrzeit abgeleitet.
Wenn du im Debugger testest, verfälscht das das Ergebnis. Es ist also eine Frage des Timings.
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011