Zufällige Passwörter generieren


229

Wenn ein Benutzer auf unserer Website sein Passwort verliert und zur Seite "Passwort verloren" wechselt, müssen wir ihm ein neues temporäres Passwort geben. Es macht mir nichts aus, wie zufällig dies ist oder ob es allen "benötigten" starken Passwortregeln entspricht. Ich möchte ihnen nur ein Passwort geben, das sie später ändern können.

Die Anwendung ist eine in C # geschriebene Webanwendung. Also dachte ich daran, gemein zu sein und den einfachen Weg zu gehen, einen Teil eines Guid zu benutzen. dh

Guid.NewGuid().ToString("d").Substring(1,8)

Vorschläge? Gedanken?


12
Ein paar gute Lösungen hier, aber ein kleiner Rat: Generieren Sie keine Passwörter, die eines dieser Zeichen enthalten: Oo0Ili (Sie sehen warum) :)
stian.net

2
Ich habe eine Antwort hinzugefügt, die KeePass als Passwortgenerator verwendet, und von den vielen verfügbaren Optionen habe ich auch die Option hinzugefügt, ähnliche Zeichen auszuschließen, wie von @ stian.net erwähnt.
Peter

Antworten:


570

7
Wusste nicht, dass das Framework eine solche Methode hat! Genial! Tausche meinen aktuellen Code dafür aus!
FryHard

35
Ich fand es, nachdem ich fast einen Tag damit verbracht hatte, meinen eigenen PW-Gen-Code zu perfektionieren. Bild wie ich mich fühlte;)
Rik

16
AFAIK Diese Methode generiert kein Kennwort, das einer Kennwortrichtlinie in der Domäne entspricht, sodass sie nicht für jede Verwendung geeignet ist.
Teebot

19
Das Hauptproblem bei dieser Lösung besteht darin, dass Sie den Zeichensatz nicht steuern können, sodass Sie visuell nicht eindeutige Zeichen (0oOl1i! |) Nicht entfernen können, was in der Praxis sehr wichtig sein kann.
David Hammond

19
Irgendwas für ASP.NET Core?
Shashwat

112
public string CreatePassword(int length)
{
        const string valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            res.Append(valid[rnd.Next(valid.Length)]);
        }
        return res.ToString();
}

Dies hat den guten Vorteil, dass Sie aus einer Liste verfügbarer Zeichen für das generierte Kennwort auswählen können (z. B. nur Ziffern, nur Groß- oder Kleinbuchstaben usw.).


2
Diese Methode (Basis 62) ist in Bezug auf die Stärke der GUID (Basis 16) überlegen: Eine 8-Zeichen-Hex-Zeichenfolge entspricht einer alphanumerischen Zeichenfolge mit 4 bis 5 Zeichen
Jimmy

57
Randomist nicht kryptografisch sicher; System.Security.Cryptography.RNGCryptoServiceProviderist eine bessere Wahl.
Anaximander

3
Dies würde bei jedem Aufruf der Methode dasselbe Kennwort generieren, da die Random-Klasse jedes Mal instanziiert wird. Dies könnte sichergestellt werden, indem Random aus dieser Methode entfernt und die Instanz wiederverwendet wird.
Jon

6
Nein, würde es nicht. Es sei denn, zwei Personen haben beschlossen, die Passwörter zur gleichen Uhrzeit zu ändern.
Radu094

10
Zitat aus Frage: egal "ob es mit allen" benötigten "strengen Passwortregeln übereinstimmt" ... danke, dass Sie diese Antwort abgelehnt haben
Radu094

35

Die Hauptziele meines Codes sind:

  1. Die Verteilung der Zeichenfolgen ist nahezu gleichmäßig (kleinere Abweichungen sind nicht wichtig, solange sie klein sind).
  2. Es werden mehr als ein paar Milliarden Zeichenfolgen für jeden Argumentsatz ausgegeben. Das Generieren einer 8-stelligen Zeichenfolge (~ 47 Bit Entropie) ist bedeutungslos, wenn Ihr PRNG nur 2 Milliarden (31 Bit Entropie) unterschiedliche Werte generiert.
  3. Es ist sicher, da ich erwarte, dass Leute dies für Passwörter oder andere Sicherheitstoken verwenden.

Die erste Eigenschaft wird erreicht, indem ein 64-Bit-Wert modulo der Alphabetgröße verwendet wird. Bei kleinen Alphabeten (wie den 62 Zeichen aus der Frage) führt dies zu einer vernachlässigbaren Verzerrung. Die zweite und dritte Eigenschaft werden durch Verwendung von RNGCryptoServiceProvideranstelle von erreicht System.Random.

using System;
using System.Security.Cryptography;

public static string GetRandomAlphanumericString(int length)
{
    const string alphanumericCharacters =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
        "abcdefghijklmnopqrstuvwxyz" +
        "0123456789";
    return GetRandomString(length, alphanumericCharacters);
}

public static string GetRandomString(int length, IEnumerable<char> characterSet)
{
    if (length < 0)
        throw new ArgumentException("length must not be negative", "length");
    if (length > int.MaxValue / 8) // 250 million chars ought to be enough for anybody
        throw new ArgumentException("length is too big", "length");
    if (characterSet == null)
        throw new ArgumentNullException("characterSet");
    var characterArray = characterSet.Distinct().ToArray();
    if (characterArray.Length == 0)
        throw new ArgumentException("characterSet must not be empty", "characterSet");

    var bytes = new byte[length * 8];
    new RNGCryptoServiceProvider().GetBytes(bytes);
    var result = new char[length];
    for (int i = 0; i < length; i++)
    {
        ulong value = BitConverter.ToUInt64(bytes, i * 8);
        result[i] = characterArray[value % (uint)characterArray.Length];
    }
    return new string(result);
}

(Dies ist eine Kopie meiner Antwort auf Wie kann ich zufällige alphanumerische Zeichenfolgen mit 8 Zeichen in C # generieren? )


1
Wenn UInt64.MaxValue nicht gleichmäßig durch characterArray.Length teilbar ist, werden die zufällig ausgewählten Zeichen nicht gleichmäßig verteilt (obwohl dies ein sehr kleiner Effekt ist).
Jeff Walker Code Ranger

1
@ JeffWalkerCodeRanger Deshalb habe ich vernachlässigbare Voreingenommenheit gesagt, keine Voreingenommenheit. Selbst mit einem Petabyte Ausgabe haben Sie weniger als 1%, um dies von einem perfekt unvoreingenommenen String-Generator zu unterscheiden. Die zusätzliche Komplexität der perfekten Unparteilichkeit ist den eher theoretischen Gewinn an Zufälligkeit hier eindeutig nicht wert.
CodesInChaos

9
Ersetzen Sie für Benutzer von .NET Core "new RNGCryptoServiceProvider (). GetBytes (bytes);" mit "System.Security.Cryptography.RandomNumberGenerator.Create (). GetBytes (Bytes);"
NPNelson

24
public string GenerateToken(int length)
{
    using (RNGCryptoServiceProvider cryptRNG = new RNGCryptoServiceProvider())
    {
        byte[] tokenBuffer = new byte[length];
        cryptRNG.GetBytes(tokenBuffer);
        return Convert.ToBase64String(tokenBuffer);
    }
}

(Sie können auch die Klasse, in der diese Methode lebt, IDisposable implementieren lassen, einen Verweis auf die enthalten RNGCryptoServiceProviderund ordnungsgemäß entsorgen, um zu vermeiden, dass sie wiederholt instanziiert wird.)

Es wurde angemerkt, dass die Ausgabelänge immer ein Vielfaches von 4 ist, da dies eine Basis-64-Zeichenfolge zurückgibt, wobei der zusätzliche Platz =als Füllzeichen verwendet wird. Der lengthParameter gibt die Länge des Bytepuffers an, nicht die Ausgabezeichenfolge (und ist daher möglicherweise nicht der beste Name für diesen Parameter, jetzt denke ich darüber nach). Dies steuert, wie viele Bytes Entropie das Passwort haben wird. Da base-64 jedoch einen 4-stelligen Block verwendet, um alle 3 Bytes der Eingabe zu codieren, wird, wenn Sie nach einer Länge fragen, die kein Vielfaches von 3 ist, ein zusätzlicher "Leerzeichen" vorhanden sein, der =zum Füllen des verwendet wird extra.

Wenn Sie aus irgendeinem Grund keine Base-64-Zeichenfolgen verwenden möchten, können Sie den Convert.ToBase64String()Aufruf entweder durch eine Konvertierung in eine reguläre Zeichenfolge oder durch eine der EncodingMethoden ersetzen . z.B. Encoding.UTF8.GetString(tokenBuffer)- Stellen Sie einfach sicher, dass Sie einen Zeichensatz auswählen, der den gesamten Wertebereich des RNG darstellt und Zeichen erzeugt, die mit dem Ort kompatibel sind, an den Sie diesen senden oder speichern. Wenn Sie beispielsweise Unicode verwenden, werden in der Regel viele chinesische Schriftzeichen angezeigt. Die Verwendung von base-64 garantiert einen weitgehend kompatiblen Zeichensatz, und die Eigenschaften einer solchen Zeichenfolge sollten sie nicht weniger sicher machen, solange Sie einen anständigen Hashing-Algorithmus verwenden.


Ich denke, Sie wollen tokenBuffer dort platzieren, wo Sie linkBuf haben.
PIntag

Wenn ich diesen Code verwende und eine Länge von 10 übergebe, ist die zurückgegebene Zeichenfolge immer 16 Zeichen lang und die letzten 2 Zeichen sind immer "==". Benutze ich es falsch? Ist die Länge in hex angegeben?
PIntag

1
Die angegebene Länge ist die Anzahl der Bytes der Zufälligkeit (oder "Entropie", wie es technisch bekannt ist). Der zurückgegebene Wert ist jedoch Base-64-codiert. Dies bedeutet, dass die Ausgabelänge aufgrund der Funktionsweise der Base-64-Codierung immer ein Vielfaches von 4 beträgt. Manchmal sind dies mehr Zeichen, als für die Codierung aller Zeichen erforderlich sind = Zeichen, um den Rest auszufüllen.
Anaximander

1
RNGCryptoServiceProvider ist ein IDisposable, daher würde ich es mit dem using-Muster implementieren (dh using (var cryptRNG = new RNGCryptoServiceProvider ()) {...})
kloarubeek

@kloarubeek Ein gültiger Punkt und ein guter Vorschlag. Ich habe das meinem Codebeispiel hinzugefügt.
Anaximander

20

Dies ist viel größer, aber ich denke, es sieht etwas umfassender aus: http://www.obviex.com/Samples/Password.aspx

///////////////////////////////////////////////////////////////////////////////
// SAMPLE: Generates random password, which complies with the strong password
//         rules and does not contain ambiguous characters.
//
// To run this sample, create a new Visual C# project using the Console
// Application template and replace the contents of the Class1.cs file with
// the code below.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// 
// Copyright (C) 2004 Obviex(TM). All rights reserved.
// 
using System;
using System.Security.Cryptography;

/// <summary>
/// This class can generate random passwords, which do not include ambiguous 
/// characters, such as I, l, and 1. The generated password will be made of
/// 7-bit ASCII symbols. Every four characters will include one lower case
/// character, one upper case character, one number, and one special symbol
/// (such as '%') in a random order. The password will always start with an
/// alpha-numeric character; it will not start with a special symbol (we do
/// this because some back-end systems do not like certain special
/// characters in the first position).
/// </summary>
public class RandomPassword
{
    // Define default min and max password lengths.
    private static int DEFAULT_MIN_PASSWORD_LENGTH  = 8;
    private static int DEFAULT_MAX_PASSWORD_LENGTH  = 10;

    // Define supported password characters divided into groups.
    // You can add (or remove) characters to (from) these groups.
    private static string PASSWORD_CHARS_LCASE  = "abcdefgijkmnopqrstwxyz";
    private static string PASSWORD_CHARS_UCASE  = "ABCDEFGHJKLMNPQRSTWXYZ";
    private static string PASSWORD_CHARS_NUMERIC= "23456789";
    private static string PASSWORD_CHARS_SPECIAL= "*$-+?_&=!%{}/";

    /// <summary>
    /// Generates a random password.
    /// </summary>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    /// <remarks>
    /// The length of the generated password will be determined at
    /// random. It will be no shorter than the minimum default and
    /// no longer than maximum default.
    /// </remarks>
    public static string Generate()
    {
        return Generate(DEFAULT_MIN_PASSWORD_LENGTH, 
                        DEFAULT_MAX_PASSWORD_LENGTH);
    }

    /// <summary>
    /// Generates a random password of the exact length.
    /// </summary>
    /// <param name="length">
    /// Exact password length.
    /// </param>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    public static string Generate(int length)
    {
        return Generate(length, length);
    }

    /// <summary>
    /// Generates a random password.
    /// </summary>
    /// <param name="minLength">
    /// Minimum password length.
    /// </param>
    /// <param name="maxLength">
    /// Maximum password length.
    /// </param>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    /// <remarks>
    /// The length of the generated password will be determined at
    /// random and it will fall with the range determined by the
    /// function parameters.
    /// </remarks>
    public static string Generate(int   minLength,
                                  int   maxLength)
    {
        // Make sure that input parameters are valid.
        if (minLength <= 0 || maxLength <= 0 || minLength > maxLength)
            return null;

        // Create a local array containing supported password characters
        // grouped by types. You can remove character groups from this
        // array, but doing so will weaken the password strength.
        char[][] charGroups = new char[][] 
        {
            PASSWORD_CHARS_LCASE.ToCharArray(),
            PASSWORD_CHARS_UCASE.ToCharArray(),
            PASSWORD_CHARS_NUMERIC.ToCharArray(),
            PASSWORD_CHARS_SPECIAL.ToCharArray()
        };

        // Use this array to track the number of unused characters in each
        // character group.
        int[] charsLeftInGroup = new int[charGroups.Length];

        // Initially, all characters in each group are not used.
        for (int i=0; i<charsLeftInGroup.Length; i++)
            charsLeftInGroup[i] = charGroups[i].Length;

        // Use this array to track (iterate through) unused character groups.
        int[] leftGroupsOrder = new int[charGroups.Length];

        // Initially, all character groups are not used.
        for (int i=0; i<leftGroupsOrder.Length; i++)
            leftGroupsOrder[i] = i;

        // Because we cannot use the default randomizer, which is based on the
        // current time (it will produce the same "random" number within a
        // second), we will use a random number generator to seed the
        // randomizer.

        // Use a 4-byte array to fill it with random bytes and convert it then
        // to an integer value.
        byte[] randomBytes = new byte[4];

        // Generate 4 random bytes.
        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
        rng.GetBytes(randomBytes);

        // Convert 4 bytes into a 32-bit integer value.
        int seed = BitConverter.ToInt32(randomBytes, 0);

        // Now, this is real randomization.
        Random  random  = new Random(seed);

        // This array will hold password characters.
        char[] password = null;

        // Allocate appropriate memory for the password.
        if (minLength < maxLength)
            password = new char[random.Next(minLength, maxLength+1)];
        else
            password = new char[minLength];

        // Index of the next character to be added to password.
        int nextCharIdx;

        // Index of the next character group to be processed.
        int nextGroupIdx;

        // Index which will be used to track not processed character groups.
        int nextLeftGroupsOrderIdx;

        // Index of the last non-processed character in a group.
        int lastCharIdx;

        // Index of the last non-processed group.
        int lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;

        // Generate password characters one at a time.
        for (int i=0; i<password.Length; i++)
        {
            // If only one character group remained unprocessed, process it;
            // otherwise, pick a random character group from the unprocessed
            // group list. To allow a special character to appear in the
            // first position, increment the second parameter of the Next
            // function call by one, i.e. lastLeftGroupsOrderIdx + 1.
            if (lastLeftGroupsOrderIdx == 0)
                nextLeftGroupsOrderIdx = 0;
            else
                nextLeftGroupsOrderIdx = random.Next(0, 
                                                     lastLeftGroupsOrderIdx);

            // Get the actual index of the character group, from which we will
            // pick the next character.
            nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];

            // Get the index of the last unprocessed characters in this group.
            lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;

            // If only one unprocessed character is left, pick it; otherwise,
            // get a random character from the unused character list.
            if (lastCharIdx == 0)
                nextCharIdx = 0;
            else
                nextCharIdx = random.Next(0, lastCharIdx+1);

            // Add this character to the password.
            password[i] = charGroups[nextGroupIdx][nextCharIdx];

            // If we processed the last character in this group, start over.
            if (lastCharIdx == 0)
                charsLeftInGroup[nextGroupIdx] = 
                                          charGroups[nextGroupIdx].Length;
            // There are more unprocessed characters left.
            else
            {
                // Swap processed character with the last unprocessed character
                // so that we don't pick it until we process all characters in
                // this group.
                if (lastCharIdx != nextCharIdx)
                {
                    char temp = charGroups[nextGroupIdx][lastCharIdx];
                    charGroups[nextGroupIdx][lastCharIdx] = 
                                charGroups[nextGroupIdx][nextCharIdx];
                    charGroups[nextGroupIdx][nextCharIdx] = temp;
                }
                // Decrement the number of unprocessed characters in
                // this group.
                charsLeftInGroup[nextGroupIdx]--;
            }

            // If we processed the last group, start all over.
            if (lastLeftGroupsOrderIdx == 0)
                lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
            // There are more unprocessed groups left.
            else
            {
                // Swap processed group with the last unprocessed group
                // so that we don't pick it until we process all groups.
                if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
                {
                    int temp = leftGroupsOrder[lastLeftGroupsOrderIdx];
                    leftGroupsOrder[lastLeftGroupsOrderIdx] = 
                                leftGroupsOrder[nextLeftGroupsOrderIdx];
                    leftGroupsOrder[nextLeftGroupsOrderIdx] = temp;
                }
                // Decrement the number of unprocessed groups.
                lastLeftGroupsOrderIdx--;
            }
        }

        // Convert password characters into a string and return the result.
        return new string(password);
     }
}

/// <summary>
/// Illustrates the use of the RandomPassword class.
/// </summary>
public class RandomPasswordTest
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // Print 100 randomly generated passwords (8-to-10 char long).
        for (int i=0; i<100; i++)
            Console.WriteLine(RandomPassword.Generate(8, 10));
    }
}
//
// END OF FILE
///////////////////////////////////////////////////////////////////////////////

2
Es stellt sich heraus, dass das Framework dies unterstützt. Also akzeptiere ich diese Antwort eher!
FryHard

1
Das Generieren von nur 2 ^ 31 verschiedenen Passwörtern, selbst bei langen Ausgabegrößen, ist etwas zu niedrig. Könnte gegen Online-Angriffe ausreichen, ist aber für Offline-Angriffe sicherlich zu klein. => Ich würde das nicht empfehlen.
CodesInChaos

Dies ist immer noch eine gute Antwort, da die "integrierte" Unterstützung wirklich Mitgliedschaft ist. Was ist, wenn Sie sich entschieden haben, die ASP.NET-Mitgliedschaft nicht zu verwenden? Es funktioniert immer noch, da die Abhängigkeit System.Web.dll ist, aber es ist etwas umständlich, da die Methode nicht in sich geschlossen ist. @GEOCHET: Danke, dass du diese Alternative gepostet hast.
Chris Gomez

8

Ich weiß, dass dies ein alter Thread ist, aber ich habe eine ziemlich einfache Lösung für jemanden. Einfach zu implementieren, leicht zu verstehen und leicht zu validieren.

Beachten Sie die folgende Anforderung:

Ich muss ein zufälliges Passwort generieren, das mindestens 2 Kleinbuchstaben, 2 Großbuchstaben und 2 Zahlen enthält. Das Passwort muss außerdem mindestens 8 Zeichen lang sein.

Der folgende reguläre Ausdruck kann diesen Fall bestätigen:

^(?=\b\w*[a-z].*[a-z]\w*\b)(?=\b\w*[A-Z].*[A-Z]\w*\b)(?=\b\w*[0-9].*[0-9]\w*\b)[a-zA-Z0-9]{8,}$

Es liegt außerhalb des Rahmens dieser Frage - aber der reguläre Ausdruck basiert auf Lookahead / Lookbehind und Lookaround .

Der folgende Code erstellt einen zufälligen Zeichensatz, der dieser Anforderung entspricht:

public static string GeneratePassword(int lowercase, int uppercase, int numerics) {
    string lowers = "abcdefghijklmnopqrstuvwxyz";
    string uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string number = "0123456789";

    Random random = new Random();

    string generated = "!";
    for (int i = 1; i <= lowercase; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            lowers[random.Next(lowers.Length - 1)].ToString()
        );

    for (int i = 1; i <= uppercase; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            uppers[random.Next(uppers.Length - 1)].ToString()
        );

    for (int i = 1; i <= numerics; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            number[random.Next(number.Length - 1)].ToString()
        );

    return generated.Replace("!", string.Empty);

}

Um die oben genannte Anforderung zu erfüllen, rufen Sie einfach Folgendes an:

String randomPassword = GeneratePassword(3, 3, 3);

Der Code beginnt mit einem ungültigen Zeichen ( "!"), sodass die Zeichenfolge eine Länge hat, in die neue Zeichen eingefügt werden können.

Anschließend wird eine Schleife von 1 bis zur Anzahl der erforderlichen Kleinbuchstaben ausgeführt. Bei jeder Iteration wird ein zufälliges Element aus der Kleinbuchstabenliste abgerufen und an einer zufälligen Stelle in der Zeichenfolge eingefügt.

Anschließend wird die Schleife für Großbuchstaben und für Zahlen wiederholt.

Auf diese Weise erhalten Sie Zeichenfolgen mit der Länge =, lowercase + uppercase + numericsin die Klein-, Groß- und Zahlenzeichen der gewünschten Anzahl in zufälliger Reihenfolge gesetzt wurden.


3
Nicht System.Randomfür sicherheitskritische Dinge wie Passwörter verwenden. Verwenden SieRNGCryptoServiceProvider
CodesInChaos

lowers[random.Next(lowers.Length - 1)].ToString() Dieser Code generiert niemals ein 'z'. random.Next erzeugt Ganzzahlen, die kleiner als die angegebene Zahl sind. Daher sollten Sie diese zusätzliche Zahl nicht von der Länge abziehen.
Notbono

6

Für diese Art von Passwort verwende ich normalerweise ein System, das wahrscheinlich leichter "verwendete" Passwörter generiert. Kurz, oft aus aussprechbaren Fragmenten und einigen Zahlen zusammengesetzt und ohne Mehrdeutigkeit zwischen den Zeichen (ist das eine 0 oder eine O? A 1 oder eine I?). Etwas wie

string[] words = { 'bur', 'ler', 'meh', 'ree' };
string word = "";

Random rnd = new Random();
for (i = 0; i < 3; i++)
   word += words[rnd.Next(words.length)]

int numbCount = rnd.Next(4);
for (i = 0; i < numbCount; i++)
  word += (2 + rnd.Next(7)).ToString();

return word;

(Wird direkt in den Browser eingegeben, daher nur als Richtlinie verwendet. Fügen Sie außerdem weitere Wörter hinzu.)


6

Ich mag die Passwörter, die Membership.GeneratePassword () erstellt, nicht, da sie zu hässlich sind und zu viele Sonderzeichen haben.

Dieser Code generiert ein 10-stelliges, nicht zu hässliches Passwort.

string password = Guid.NewGuid().ToString("N").ToLower()
                      .Replace("1", "").Replace("o", "").Replace("0","")
                      .Substring(0,10);

Sicher, ich könnte einen Regex verwenden, um alle Ersetzungen durchzuführen, aber dies ist besser lesbar und wartbar IMO.


2
Eine GUID sollte nicht als Krypto PRNG
CodesInChaos

3
Wenn Sie diese Methode verwenden möchten, können Sie .ToString ("N") verwenden und müssen das "-" nicht ersetzen. Es ist auch nicht erforderlich, "l" zu ersetzen, da es sich nicht um eine hexadezimale Ziffer handelt.
JackAce

Sehen Sie total, warum Sie das getan haben. Ich brauchte nur ein kurzlebiges Passwort (weniger als einen Tag), das nicht zu eindeutig pro Benutzer sein musste. Das Herausziehen der Einsen und Nullen ist eine großartige Möglichkeit, die Verwirrung zu beseitigen. Ich habe meine auch nur in Großbuchstaben verschoben und dann die Länge auf 6 gekürzt. Wie auch der Vorschlag 'N'. Vielen Dank!
Bill Noel

6

Ich habe diese Klasse erstellt , die RNGCryptoServiceProvider verwendet und flexibel ist. Beispiel:

var generator = new PasswordGenerator(minimumLengthPassword: 8,
                                      maximumLengthPassword: 15,
                                      minimumUpperCaseChars: 2,
                                      minimumNumericChars: 3,
                                      minimumSpecialChars: 2);
string password = generator.Generate();

Das ist großartig, was ist die Lizenz für diese Klasse? Kann ich es benutzen?
Codeulike

Verwenden Sie es wie Sie wollen!
Alex Siepman

3

Ich habe diese Methode ähnlich der im Mitgliedschaftsanbieter verfügbaren erstellt. Dies ist nützlich, wenn Sie die Webreferenz in einigen Anwendungen nicht hinzufügen möchten.

Es funktioniert großartig.

public static string GeneratePassword(int Length, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
        Random rd = new Random();

        if (NonAlphaNumericChars > Length || Length <= 0 || NonAlphaNumericChars < 0)
            throw new ArgumentOutOfRangeException();

            char[] pass = new char[Length];
            int[] pos = new int[Length];
            int i = 0, j = 0, temp = 0;
            bool flag = false;

            //Random the position values of the pos array for the string Pass
            while (i < Length - 1)
            {
                j = 0;
                flag = false;
                temp = rd.Next(0, Length);
                for (j = 0; j < Length; j++)
                    if (temp == pos[j])
                    {
                        flag = true;
                        j = Length;
                    }

                if (!flag)
                {
                    pos[i] = temp;
                    i++;
                }
            }

            //Random the AlphaNumericChars
            for (i = 0; i < Length - NonAlphaNumericChars; i++)
                pass[i] = allowedChars[rd.Next(0, allowedChars.Length)];

            //Random the NonAlphaNumericChars
            for (i = Length - NonAlphaNumericChars; i < Length; i++)
                pass[i] = allowedNonAlphaNum[rd.Next(0, allowedNonAlphaNum.Length)];

            //Set the sorted array values by the pos array for the rigth posistion
            char[] sorted = new char[Length];
            for (i = 0; i < Length; i++)
                sorted[i] = pass[pos[i]];

            string Pass = new String(sorted);

            return Pass;
    }

6
Nicht System.Randomfür sicherheitskritische Dinge wie Passwörter verwenden. Verwenden SieRNGCryptoServiceProvider
CodesInChaos

3

Ich war immer sehr zufrieden mit dem in KeePass integrierten Passwortgenerator. Da KeePass ein .NET-Programm und Open Source ist, habe ich mich entschlossen, den Code ein wenig zu vertiefen. Am Ende habe ich nur KeePass.exe, die in der Standardanwendung installierte Kopie, als Referenz in meinem Projekt referenziert und den folgenden Code geschrieben. Sie können sehen, wie flexibel es dank KeePass ist. Sie können die Länge angeben, welche Zeichen eingeschlossen werden sollen / nicht usw.

using KeePassLib.Cryptography.PasswordGenerator;
using KeePassLib.Security;


public static string GeneratePassword(int passwordLength, bool lowerCase, bool upperCase, bool digits,
        bool punctuation, bool brackets, bool specialAscii, bool excludeLookAlike)
    {
        var ps = new ProtectedString();
        var profile = new PwProfile();
        profile.CharSet = new PwCharSet();
        profile.CharSet.Clear();

        if (lowerCase)
            profile.CharSet.AddCharSet('l');
        if(upperCase)
            profile.CharSet.AddCharSet('u');
        if(digits)
            profile.CharSet.AddCharSet('d');
        if (punctuation)
            profile.CharSet.AddCharSet('p');
        if (brackets)
            profile.CharSet.AddCharSet('b');
        if (specialAscii)
            profile.CharSet.AddCharSet('s');

        profile.ExcludeLookAlike = excludeLookAlike;
        profile.Length = (uint)passwordLength;
        profile.NoRepeatingCharacters = true;

        KeePassLib.Cryptography.PasswordGenerator.PwGenerator.Generate(out ps, profile, null, _pool);

        return ps.ReadString();
    }

2
public static string GeneratePassword(int passLength) {
        var chars = "abcdefghijklmnopqrstuvwxyz@#$&ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var random = new Random();
        var result = new string(
            Enumerable.Repeat(chars, passLength)
                      .Select(s => s[random.Next(s.Length)])
                      .ToArray());
        return result;
    }

Bitte erklären Sie Ihre Antwort
Linus

1
Diese Funktion funktioniert mit ein paar Änderungen sehr gut. 1. Entropie hinzugefügt, wenn Sie mehrere Anrufe gleichzeitig tätigen. Dies bedeutet Sleep () oder eine andere Entropie verursachende Funktion zwischen Aufrufen. 2. Erhöhen Sie die Anzahl und Zufälligkeit der Quellzeichen. Ich habe eine Reihe von 500 Zeichen-Passwörtern mit Tastatur erstellt, mit Ausnahme einer Reihe ähnlicher und anderer entkommener Zeichen, mit denen ich mich nicht befassen wollte, und die resultierende 2000-Zeichenfolge verwendet. Die Zufälligkeit nach nur 100 ms Entropie war ziemlich gut.
Wizengamot

2

Ich werde dem Topf eine weitere schlecht beratene Antwort hinzufügen.

Ich habe einen Anwendungsfall, in dem ich zufällige Passwörter für die Maschine-Maschine-Kommunikation benötige, sodass ich keine Anforderungen an die menschliche Lesbarkeit habe. Ich habe Membership.GeneratePasswordin meinem Projekt auch keinen Zugriff darauf und möchte die Abhängigkeit nicht hinzufügen.

Ich bin mir ziemlich sicher, dass Membership.GeneratePasswordich etwas Ähnliches mache, aber hier können Sie die Pools von Charakteren einstellen, aus denen Sie zeichnen können.

public static class PasswordGenerator
{
    private readonly static Random _rand = new Random();

    public static string Generate(int length = 24)
    {
        const string lower = "abcdefghijklmnopqrstuvwxyz";
        const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string number = "1234567890";
        const string special = "!@#$%^&*_-=+";

        // Get cryptographically random sequence of bytes
        var bytes = new byte[length];
        new RNGCryptoServiceProvider().GetBytes(bytes);

        // Build up a string using random bytes and character classes
        var res = new StringBuilder();
        foreach(byte b in bytes)
        {
            // Randomly select a character class for each byte
            switch (_rand.Next(4))
            {
                // In each case use mod to project byte b to the correct range
                case 0:
                    res.Append(lower[b % lower.Count()]);
                    break;
                case 1:
                    res.Append(upper[b % upper.Count()]);
                    break;
                case 2:
                    res.Append(number[b % number.Count()]);
                    break;
                case 3:
                    res.Append(special[b % special.Count()]);
                    break;
            }
        }
        return res.ToString();
    }
}

Und einige Beispielausgaben:

PasswordGenerator.Generate(12)
"pzY=64@-ChS$"
"BG0OsyLbYnI_"
"l9#5^2&adj_i"
"#++Ws9d$%O%X"
"IWhdIN-#&O^s"

Um Beschwerden über die Verwendung von vorzubeugen Random: Die Hauptquelle für Zufälligkeit ist immer noch das Krypto-RNG. Selbst wenn Sie die Sequenz, aus der sie hervorgeht Random(sagen wir, sie wurde nur produziert 1), deterministisch vorbestimmen könnten, würden Sie das nächste Zeichen, das ausgewählt werden würde, nicht kennen (obwohl dies den Bereich der Möglichkeiten einschränken würde ).

Eine einfache Erweiterung wäre das Hinzufügen einer Gewichtung zu den verschiedenen Zeichensätzen. Dies könnte so einfach sein, wie den Maximalwert zu erhöhen und Durchfallfälle hinzuzufügen, um das Gewicht zu erhöhen.

switch (_rand.Next(6))
{
    // Prefer letters 2:1
    case 0:
    case 1:
        res.Append(lower[b % lower.Count()]);
        break;
    case 2:
    case 3:
        res.Append(upper[b % upper.Count()]);
        break;
    case 4:
        res.Append(number[b % number.Count()]);
        break;
    case 5:
        res.Append(special[b % special.Count()]);
        break;
}

Für einen humanistischeren Zufallspasswortgenerator habe ich einmal ein Aufforderungssystem unter Verwendung der EFF-Würfelwortliste implementiert .


1

Ich mag es, Passwörter zu generieren, genau wie Software-Schlüssel zu generieren. Sie sollten aus einer Reihe von Zeichen auswählen, die einer bewährten Methode folgen. Nehmen Sie die Antwort von @ Radu094 und ändern Sie sie, um den bewährten Methoden zu folgen. Fügen Sie nicht jeden einzelnen Buchstaben in das Zeichenfeld ein. Einige Briefe sind am Telefon schwerer zu sagen oder zu verstehen.

Sie sollten auch eine Prüfsumme für das generierte Kennwort in Betracht ziehen, um sicherzustellen, dass es von Ihnen generiert wurde. Ein guter Weg, dies zu erreichen, ist die Verwendung des LUHN-Algorithmus .


1

Hier ist was ich schnell zusammengestellt habe.

    public string GeneratePassword(int len)
    {
        string res = "";
        Random rnd = new Random();
        while (res.Length < len) res += (new Func<Random, string>((r) => {
            char c = (char)((r.Next(123) * DateTime.Now.Millisecond % 123)); 
            return (Char.IsLetterOrDigit(c)) ? c.ToString() : ""; 
        }))(rnd);
        return res;
    }

1

Ich benutze diesen Code, um ein Passwort mit einer Balance aus alphabetischen, numerischen und nicht_alpha_numerischen Zeichen zu generieren.

public static string GeneratePassword(int Length, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
        string pass = "";
        Random rd = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < Length; i++)
        {
            if (rd.Next(1) > 0 && NonAlphaNumericChars > 0)
            {
                pass += allowedNonAlphaNum[rd.Next(allowedNonAlphaNum.Length)];
                NonAlphaNumericChars--;
            }
            else
            {
                pass += allowedChars[rd.Next(allowedChars.Length)];
            }
        }
        return pass;
    }

0

Das ist kurz und es funktioniert gut für mich.

public static string GenerateRandomCode(int length)
{
    Random rdm = new Random();
    StringBuilder sb = new StringBuilder();

    for(int i = 0; i < length; i++)
        sb.Append(Convert.ToChar(rdm.Next(101,132)));

    return sb.ToString();
}

Es mag "funktionieren", aber es ist sicherlich nicht sicher. Passwörter müssen sicher sein.
CodesInChaos

Ich denke, zufällige Passwörter sind temporäre Passwörter. Sehen Sie nicht, warum sie sicher sein müssen, und selbst wenn dies der Fall ist, können Sie dem Bereich Zahlen und Sonderzeichen hinzufügen.
user1058637

1
Das Hinzufügen von Zahlen und Sonderzeichen verbessert die Sicherheit nicht, wenn Sie sie mit einem vorhersehbaren PRNG generieren. Wenn Sie wissen, wann ein Passwort generiert wurde, können Sie es auf wenige Kandidaten eingrenzen.
CodesInChaos

0

Auf meiner Website verwende ich diese Methode:

    //Symb array
    private const string _SymbolsAll = "~`!@#$%^&*()_+=-\\|[{]}'\";:/?.>,<";

    //Random symb
    public string GetSymbol(int Length)
    {
        Random Rand = new Random(DateTime.Now.Millisecond);
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < Length; i++)
            result.Append(_SymbolsAll[Rand.Next(0, _SymbolsAll.Length)]);
        return result.ToString();
    }

Bearbeiten Sie die Zeichenfolge _SymbolsAllfür Ihre Array-Liste.


Wie bereits in der Bearbeitungsbeschreibung angegeben. Wenn Sie auf Ihre Website verlinken, ohne dass es sich um eine Code-Referenz handelt, machen Sie reine Werbung, wodurch Spam entsteht. Entfernen Sie diesen Link aus Ihrer Antwort.
Bowdzone

0

Der akzeptierten Antwort wurde ein zusätzlicher Code hinzugefügt. Es verbessert die Antworten nur mit Random und ermöglicht einige Passwortoptionen. Ich mochte auch einige der Optionen aus der KeePass-Antwort, wollte aber die ausführbare Datei nicht in meine Lösung aufnehmen.

private string RandomPassword(int length, bool includeCharacters, bool includeNumbers, bool includeUppercase, bool includeNonAlphaNumericCharacters, bool includeLookAlikes)
{
    if (length < 8 || length > 128) throw new ArgumentOutOfRangeException("length");
    if (!includeCharacters && !includeNumbers && !includeNonAlphaNumericCharacters) throw new ArgumentException("RandomPassword-Key arguments all false, no values would be returned");

    string pw = "";
    do
    {
        pw += System.Web.Security.Membership.GeneratePassword(128, 25);
        pw = RemoveCharacters(pw, includeCharacters, includeNumbers, includeUppercase, includeNonAlphaNumericCharacters, includeLookAlikes);
    } while (pw.Length < length);

    return pw.Substring(0, length);
}

private string RemoveCharacters(string passwordString, bool includeCharacters, bool includeNumbers, bool includeUppercase, bool includeNonAlphaNumericCharacters, bool includeLookAlikes)
{
    if (!includeCharacters)
    {
        var remove = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
        foreach (string r in remove)
        {
            passwordString = passwordString.Replace(r, string.Empty);
            passwordString = passwordString.Replace(r.ToUpper(), string.Empty);
        }
    }

    if (!includeNumbers)
    {
        var remove = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    if (!includeUppercase)
        passwordString = passwordString.ToLower();

    if (!includeNonAlphaNumericCharacters)
    {
        var remove = new string[] { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "=", "{", "}", "[", "]", "|", "\\", ":", ";", "<", ">", "/", "?", "." };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    if (!includeLookAlikes)
    {
        var remove = new string[] { "(", ")", "0", "O", "o", "1", "i", "I", "l", "|", "!", ":", ";" };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    return passwordString;
}

Dies war der erste Link, als ich nach zufälligen Passwörtern gesucht habe. Das Folgende ist für die aktuelle Frage nicht relevant, könnte aber wichtig sein.

  • Basierend auf der Annahme, dass System.Web.Security.Membership.GeneratePasswordkryptografisch sicher ist und mindestens 20% der Zeichen nicht alphanumerisch sind.
  • Ich bin mir nicht sicher, ob das Entfernen von Zeichen und das Anhängen von Zeichenfolgen in diesem Fall als bewährte Methode angesehen wird und genügend Entropie bietet.
  • Möglicherweise möchten Sie eine Implementierung mit SecureString für die sichere Speicherung von Kennwörtern im Speicher in Betracht ziehen .

FYI, würden Sie nicht die KeyPass ausführbare Datei enthalten müssen, wie es Open Source ist (der Quellcode steht zum Download bereit hier )
Alex Klaus

0

validChars kann ein beliebiges Konstrukt sein, aber ich habe mich entschieden, basierend auf ASCII-Codebereichen auszuwählen, um Steuerzeichen zu entfernen. In diesem Beispiel handelt es sich um eine 12-stellige Zeichenfolge.

string validChars = String.Join("", Enumerable.Range(33, (126 - 33)).Where(i => !(new int[] { 34, 38, 39, 44, 60, 62, 96 }).Contains(i)).Select(i => { return (char)i; }));
string.Join("", Enumerable.Range(1, 12).Select(i => { return validChars[(new Random(Guid.NewGuid().GetHashCode())).Next(0, validChars.Length - 1)]; }))

0
 Generate random password of specified length with 
  - Special characters   
  - Number
  - Lowecase
  - Uppercase

  public static string CreatePassword(int length = 12)
    {
        const string lower = "abcdefghijklmnopqrstuvwxyz";
        const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string number = "1234567890";
        const string special = "!@#$%^&*";

        var middle = length / 2;
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            if (middle == length)
            {
                res.Append(number[rnd.Next(number.Length)]);
            }
            else if (middle - 1 == length)
            {
                res.Append(special[rnd.Next(special.Length)]);
            }
            else
            {
                if (length % 2 == 0)
                {
                    res.Append(lower[rnd.Next(lower.Length)]);
                }
                else
                {
                    res.Append(upper[rnd.Next(upper.Length)]);
                }
            }
        }
        return res.ToString();
    }

Code nur Antworten werden nicht empfohlen, da sie nicht viele Informationen für zukünftige Leser bieten. Bitte geben Sie eine Erklärung zu dem, was Sie geschrieben haben
WhatsThePoint

Erstellt immer wieder das gleiche Passwort. Random
Muss

Bitte beachten Sie, dass diese Antwort das gleiche Passwort generiert, wenn sie mehrmals hintereinander aufgerufen wird !!! Zwischen Aufrufen muss Entropie hinzugefügt werden, wenn Sie die Funktion verwenden möchten, um mehreren Datensätzen Kennwörter mithilfe von Code gleichzeitig zuzuweisen. Immer noch nützlich ....
Wizengamot

0

Mit diesem Paket können Sie ein zufälliges Passwort generieren und dabei fließend angeben, welche Zeichen es enthalten soll (falls erforderlich):

https://github.com/prjseal/PasswordGenerator/

Beispiel:

var pwd = new Password().IncludeLowercase().IncludeUppercase().IncludeSpecial();
var password = pwd.Next();

0

Wenn Sie die von System.Web.Security.Membership.GeneratePassword verwendete kryptografisch sichere Zufallszahlengenerierung verwenden möchten, aber den Zeichensatz auch auf alphanumerische Zeichen beschränken möchten, können Sie das Ergebnis mit einem regulären Ausdruck filtern:

static string GeneratePassword(int characterCount)
{
    string password = String.Empty;
    while(password.Length < characterCount)
        password += Regex.Replace(System.Web.Security.Membership.GeneratePassword(128, 0), "[^a-zA-Z0-9]", string.Empty);
    return password.Substring(0, characterCount);
}

-3
public string Sifre_Uret(int boy, int noalfa)
{

    //  01.03.2016   
    // Genel amaçlı şifre üretme fonksiyonu


    //Fonskiyon 128 den büyük olmasına izin vermiyor.
    if (boy > 128 ) { boy = 128; }
    if (noalfa > 128) { noalfa = 128; }
    if (noalfa > boy) { noalfa = boy; }


    string passch = System.Web.Security.Membership.GeneratePassword(boy, noalfa);

    //URL encoding ve Url Pass + json sorunu yaratabilecekler pass ediliyor.
    //Microsoft Garanti etmiyor. Alfa Sayısallar Olabiliyorimiş . !@#$%^&*()_-+=[{]};:<>|./?.
    //https://msdn.microsoft.com/tr-tr/library/system.web.security.membership.generatepassword(v=vs.110).aspx


    //URL ve Json ajax lar için filtreleme
    passch = passch.Replace(":", "z");
    passch = passch.Replace(";", "W");
    passch = passch.Replace("'", "t");
    passch = passch.Replace("\"", "r");
    passch = passch.Replace("/", "+");
    passch = passch.Replace("\\", "e");

    passch = passch.Replace("?", "9");
    passch = passch.Replace("&", "8");
    passch = passch.Replace("#", "D");
    passch = passch.Replace("%", "u");
    passch = passch.Replace("=", "4");
    passch = passch.Replace("~", "1");

    passch = passch.Replace("[", "2");
    passch = passch.Replace("]", "3");
    passch = passch.Replace("{", "g");
    passch = passch.Replace("}", "J");


    //passch = passch.Replace("(", "6");
    //passch = passch.Replace(")", "0");
    //passch = passch.Replace("|", "p");
    //passch = passch.Replace("@", "4");
    //passch = passch.Replace("!", "u");
    //passch = passch.Replace("$", "Z");
    //passch = passch.Replace("*", "5");
    //passch = passch.Replace("_", "a");

    passch = passch.Replace(",", "V");
    passch = passch.Replace(".", "N");
    passch = passch.Replace("+", "w");
    passch = passch.Replace("-", "7");





    return passch;



}

Können Sie erklären, was Ihr Code tut und warum? Aus der Bewertung
Wai Ha Lee

Nur Code-Antworten ohne Erklärung werden wahrscheinlich gelöscht.
Turm

-4

Fügen Sie einen Timer ein: timer1, 2 Schaltflächen: button1, button2, 1 textBox: textBox1 und eine comboBox: comboBox1. Stellen Sie sicher, dass Sie Folgendes deklarieren:

int count = 0;

Quellcode:

 private void button1_Click(object sender, EventArgs e)
    {
    // This clears the textBox, resets the count, and starts the timer
        count = 0;
        textBox1.Clear();
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    // This generates the password, and types it in the textBox
        count += 1;
            string possible = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
            string psw = "";
            Random rnd = new Random { };
            psw += possible[rnd.Next(possible.Length)];
            textBox1.Text += psw;
            if (count == (comboBox1.SelectedIndex + 1))
            {
                timer1.Stop();
            }
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        // This adds password lengths to the comboBox to choose from.
        comboBox1.Items.Add("1");
        comboBox1.Items.Add("2");
        comboBox1.Items.Add("3");
        comboBox1.Items.Add("4");
        comboBox1.Items.Add("5");
        comboBox1.Items.Add("6");
        comboBox1.Items.Add("7");
        comboBox1.Items.Add("8");
        comboBox1.Items.Add("9");
        comboBox1.Items.Add("10");
        comboBox1.Items.Add("11");
        comboBox1.Items.Add("12");
    }
    private void button2_click(object sender, EventArgs e)
    {
        // This encrypts the password
        tochar = textBox1.Text;
        textBox1.Clear();
        char[] carray = tochar.ToCharArray();
        for (int i = 0; i < carray.Length; i++)
        {
            int num = Convert.ToInt32(carray[i]) + 10;
            string cvrt = Convert.ToChar(num).ToString();
            textBox1.Text += cvrt;
        }
    }

1
Nicht System.Randomzur Sicherheit verwenden.
CodesInChaos
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.