Frage

So habe ich eine kleine geschrieben und von dem, was ich anfangs dachte, einfache Methode in C #. Diese statische Methode soll als einfaches Passwort Vorschlag Generator verwendet werden soll, und den Code sieht wie folgt aus:

public static string CreateRandomPassword(int outputLength, string source = "")
{
  var output = string.Empty;

  for (var i = 0; i < outputLength; i++)
  {
     var randomObj = new Random();
     output += source.Substring(randomObj.Next(source.Length), 1);
  }

  return output;
}

nenne ich diese Funktion wie folgt aus:

var randomPassword = StringHelper.CreateRandomPassword(5, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");

Nun, diese Methode fast immer zurückgeben zufällige Zeichenfolge wie "AAAAAA", "BBBBBB", "888888" etc .., wo ich dachte, es sollte Strings zurückgeben wie "A8JK2A", "82mOK7" etc.

Allerdings, und hier ist der wierd Teil; Wenn ich einen Haltepunkt setzen und Schritt für Schritt durch diese Iteration Zeile für Zeile, erhalte ich die richtige Art von Passwort zurück. In 100% der anderen Fälle, wenn Im nicht Debugging, es gibt mir wie "AAAAAA" Mist "666666", etc ..

Wie ist das möglich? Jeder Vorschlag wird sehr geschätzt! : -)

BTW, mein System: Visual Studio 2010, C # 4.0, ASP.NET MVC 3 RTM Projekt w / ASP.NET Development Server. Haben Sie nicht den Code in allen anderen Umgebungen getestet.

War es hilfreich?

Lösung

Verschieben Sie die Deklaration für die randomObj außerhalb der Schleife. Wenn Sie es debuggen, schafft sie es mit einem neuen Samen jedes Mal, weil es genug Zeitdifferenz ist für die Samen, anders zu sein. Aber wenn Sie nicht debuggen, die Saatzeit ist im Grunde das gleiche für jede Iteration der Schleife, so dass es Sie den gleichen Startwert jedes Mal ist zu geben.

Und eine kleine nit - es ist eine gute Gewohnheit, einen String eher als eine Zeichenfolge für diese Art der Sache zu verwenden, so dass Sie nicht haben erneut zu initialisieren Speicherplatz jedes Mal, wenn Sie ein Zeichen der Zeichenfolge anhängen.

Mit anderen Worten, wie folgt aus:

public static string CreateRandomPassword(int outputLength, string source = "")
{
  var output = new StringBuilder();
  var randomObj = new Random();
  for (var i = 0; i < outputLength; i++)
  {
     output.Append(source.Substring(randomObj.Next(source.Length), 1));
  }
  return output.ToString();
}

Andere Tipps

Das Verhalten Sie sehen, ist, weil Random ist zeitbasierte , und wenn Sie das Debuggen nicht fliegt durch alle 5 Wiederholungen im gleichen Moment (mehr oder weniger). Sie sind also für die erste Zufallszahl aus demselben Samen zu fragen. Wenn Sie das Debuggen, dauert es lange genug, um ein neues Saatgut jedes Mal zu erhalten.

Bewegen Sie die Deklaration von Random außerhalb der Schleife:

var randomObj = new Random();
for (var i = 0; i < outputLength; i++)
{
    output += source.Substring(randomObj.Next(source.Length), 1);
}

Jetzt sind Sie voran 5 Schritte von einem Random Seed anstelle von 1 bewegt Schritt weg von der gleichen Random Seed 5 mal .

Sie sind instanziieren eine neue Instanz von Random () bei jeder Iteration durch die Schleife mit einer neuen zeitabhängigen Samen. In Anbetracht der Granularität des Systemtakts und die Geschwindigkeit des modernen CPUs, ist dieser ziemlich viel garantiert, dass Sie einen Neustart die Pseudo-Zufallsfolge über und über mit demselben Samen.

Versuchen Sie so etwas wie die folgenden, obwohl, wenn Sie Single-threaded, Sie sicher das Schloss weglassen können ():

private static Random randomBits = new Random() ;
public static string CreateRandomPassword(int outputLength, string source = "")
{
  StringBuilder sb = new StringBuilder(outputLength) ;
  lock ( randomBits )
  {
    while ( sb.Length < outputLength )
    {
      sb.Append( randomBits.Next( source.Length) , 1 ) ;
    }
  }
  return sb.ToString() ;
}

Sie instanziiert nur die RNG einmal. Jeder zieht Bits aus dem gleichen RNG, so dass es viel mehr wie eine Quelle der Entropie verhalten soll. Wenn Sie Wiederholbarkeit für die Prüfung benötigen, verwenden Sie die Random-Konstruktor Überlastung, die Sie den Samen können liefern. Same Same == gleiche Pseudozufallsfolge.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top