Générateur de chaîne aléatoire retournant la même chaîne [dupliquer]

cette question a déjà une réponse ici:

j'ai développé un générateur de chaîne aléatoire mais il ne se comporte pas tout à fait comme je l'espère. Mon but est d'être capable d'exécuter ceci deux fois et de générer deux quatre chaînes aléatoires de caractères. Cependant, il ne génère qu'une chaîne aléatoire de quatre caractères deux fois.

voici le code et un exemple de sa sortie:

private string RandomString(int size)
{
    StringBuilder builder = new StringBuilder();
    Random random = new Random();
    char ch;
    for (int i = 0; i < size; i++)
    {
        ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));                 
        builder.Append(ch);
    }

    return builder.ToString();
}

// get 1st random string 
string Rand1 = RandomString(4);

// get 2nd random string 
string Rand2 = RandomString(4);

// create full rand string
string docNum = Rand1 + "-" + Rand2;

...et la sortie ressemble à ceci: UNTE-UNTE ...mais il devrait ressembler à quelque chose comme cet UNTE-FWNU

Comment puis-je assurer deux chaînes nettement aléatoires?

221
demandé sur Cole Johnson 2009-07-14 02:38:54

30 réponses

vous faites L'instance aléatoire dans la méthode, qui lui fait retourner les mêmes valeurs lorsqu'elle est appelée en succession rapide. Je ferais quelque chose comme ceci:

private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden
private string RandomString(int size)
    {
        StringBuilder builder = new StringBuilder();
        char ch;
        for (int i = 0; i < size; i++)
        {
            ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));                 
            builder.Append(ch);
        }

        return builder.ToString();
    }

// get 1st random string 
string Rand1 = RandomString(4);

// get 2nd random string 
string Rand2 = RandomString(4);

// creat full rand string
string docNum = Rand1 + "-" + Rand2;

(version modifiée de votre code)

302
répondu RCIX 2009-07-13 22:49:28

vous instanciez l'objet Random dans votre méthode.

l'objet Random est ensemencé à partir de l'horloge du système , ce qui signifie que si vous appelez votre méthode plusieurs fois en succession rapide il utilisera la même graine à chaque fois, ce qui signifie qu'il générera la même séquence de nombres aléatoires, ce qui signifie que vous obtiendrez la même chaîne.

pour résoudre le problème, déplacez votre instance Random en dehors de la méthode elle-même (et pendant que vous y êtes, vous pourriez vous débarrasser de cette séquence folle d'appels à Convert et Floor et NextDouble ):

private readonly Random _rng = new Random();
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

private string RandomString(int size)
{
    char[] buffer = new char[size];

    for (int i = 0; i < size; i++)
    {
        buffer[i] = _chars[_rng.Next(_chars.Length)];
    }
    return new string(buffer);
}
184
répondu LukeH 2009-07-13 23:03:54

//Un très Simple de mise en œuvre

using System.IO;   
public static string RandomStr()

{
    string rStr = Path.GetRandomFileName();
    rStr = rStr.Replace(".", ""); // For Removing the .
    return rStr;
}

//Maintenant appelez simplement RandomStr() la Méthode

134
répondu Ranvir 2010-11-09 18:20:19

aussi longtemps que vous utilisez Asp.Net 2.0 ou plus, vous pouvez également utiliser l'appel de la bibliothèque- System.Web.Security.Membership.GeneratePassword , cependant, il comprendra des caractères spéciaux.

pour obtenir 4 caractères aléatoires avec un minimum de 0 caractères spéciaux -

Membership.GeneratePassword(4, 0)
49
répondu Spongeboy 2012-06-12 06:04:47

pour s'arrêter par et ce d'avoir une chaîne aléatoire dans une seule ligne de code

int yourRandomStringLength = 12; //maximum: 32
Guid.NewGuid().ToString("N").Substring(0, yourRandomStringLength);

PS: veuillez garder à l'esprit que yourRandomStringLength ne peut pas dépasser 32 Car Guid a une longueur maximale de 32.

20
répondu Abdul Munim 2012-01-18 14:23:17

encore une autre version de string generator. Simple, sans mathématiques et chiffres magiques. Mais avec une chaîne magique qui spécifie les caractères autorisés.

mise à Jour: J'ai rendu le générateur statique, donc il ne retournera pas la même chaîne quand il est appelé plusieurs fois. Cependant ce code est pas thread-safe et est certainement pas cryptographiquement sécurisé .

Pour la génération de mot de passe System.Security.Cryptography.RNGCryptoServiceProvider doit être utilisé.

private Random _random = new Random(Environment.TickCount);

public string RandomString(int length)
{
    string chars = "0123456789abcdefghijklmnopqrstuvwxyz";
    StringBuilder builder = new StringBuilder(length);

    for (int i = 0; i < length; ++i)
        builder.Append(chars[_random.Next(chars.Length)]);

    return builder.ToString();
}
12
répondu Maksym Davydov 2017-05-23 12:34:10

cette solution est une extension de la classe Random .

Utilisation

class Program
{
    private static Random random = new Random(); 

    static void Main(string[] args)
    {
        random.NextString(10); // "cH*%I\fUWH0"
        random.NextString(10); // "Cw&N%27+EM"
        random.NextString(10); // "0LZ}nEJ}_-"
        random.NextString();   // "kFmeget80LZ}nEJ}_-"
    }
}

mise en Œuvre

public static class RandomEx
{
    /// <summary>
    /// Generates random string of printable ASCII symbols of a given length
    /// </summary>
    /// <param name="r">instance of the Random class</param>
    /// <param name="length">length of a random string</param>
    /// <returns>Random string of a given length</returns>
    public static string NextString(this Random r, int length)
    {
        var data = new byte[length];
        for (int i = 0; i < data.Length; i++)
        {
            // All ASCII symbols: printable and non-printable
            // data[i] = (byte)r.Next(0, 128);
            // Only printable ASCII
            data[i] = (byte)r.Next(32, 127);
        }
        var encoding = new ASCIIEncoding();
        return encoding.GetString(data);
    }

    /// <summary>
    /// Generates random string of printable ASCII symbols
    /// with random length of 10 to 20 chars
    /// </summary>
    /// <param name="r">instance of the Random class</param>
    /// <returns>Random string of a random length between 10 and 20 chars</returns>
    public static string NextString(this Random r)
    {
        int length  = r.Next(10, 21);
        return NextString(r, length);
    }
}
12
répondu oleksii 2014-03-25 13:27:51

Voici une autre option:

public System.String GetRandomString(System.Int32 length)
{
    System.Byte[] seedBuffer = new System.Byte[4];
    using (var rngCryptoServiceProvider = new System.Security.Cryptography.RNGCryptoServiceProvider())
    {
        rngCryptoServiceProvider.GetBytes(seedBuffer);
        System.String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        System.Random random = new System.Random(System.BitConverter.ToInt32(seedBuffer, 0));
        return new System.String(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
    }
}
10
répondu Zygimantas 2013-06-17 14:50:39

la meilleure solution est d'utiliser le générateur de nombres aléatoires en même temps que la conversion de base64

public string GenRandString(int length)
{
  byte[] randBuffer = new byte[length];
  RandomNumberGenerator.Create().GetBytes(randBuffer);
  return System.Convert.ToBase64String(randBuffer).Remove(length);
}
7
répondu Ami Luttwak 2012-09-22 11:53:31

c'est parce que chaque nouvelle instance de Random génère les mêmes nombres à partir d'être appelé si vite. ne pas continuez à créer une nouvelle instance, appelez simplement next() et déclarez votre classe aléatoire en dehors de votre méthode.

4
répondu John T 2009-07-13 22:49:03

UNE LINQ one-liner pour faire bonne mesure (en supposant un private static Random Random )...

public static string RandomString(int length)
{
    return new string(Enumerable.Range(0, length).Select(_ => (char)Random.Next('a', 'z')).ToArray());
}
4
répondu AlexFoxGill 2013-08-12 10:04:55

vous devriez avoir un Objet aléatoire de classe initié une fois dans le constructeur et réutilisé sur chaque appel (ceci continue la même séquence de nombres pseudo-aléatoires). Le constructeur sans paramétrage envoie déjà le Générateur dans l'environnement.TickCount en interne.

3
répondu Kenan E. K. 2009-07-13 22:44:12

j'ai ajouté l'option de choisir la longueur en utilisant la solution Ranvir

public static string GenerateRandomString(int length)
    {
        {
            string randomString= string.Empty;

            while (randomString.Length <= length)
            {
                randomString+= Path.GetRandomFileName();
                randomString= randomString.Replace(".", string.Empty);
            }

            return randomString.Substring(0, length);
        }
    }
2
répondu João Miguel 2012-03-27 20:43:36

voici ma modification de la réponse actuellement acceptée, que je crois qu'elle est un peu plus rapide et plus courte:

private static Random random = new Random();

private string RandomString(int size) {
    StringBuilder builder = new StringBuilder(size);
    for (int i = 0; i < size; i++)
        builder.Append((char)random.Next(0x41, 0x5A));
    return builder.ToString();
}

Remarquez que je n'ai pas utiliser tous les multiplication des, Math.floor() , Convert etc.

EDIT: random.Next(0x41, 0x5A) peut être modifié à n'importe quelle plage de caractères Unicode.

2
répondu quantum 2012-11-01 02:57:17

ma méthode RandomString() pour générer une chaîne aléatoire.

private static readonly Random _rand = new Random();

/// <summary>
/// Generate a random string.
/// </summary>
/// <param name="length">The length of random string. The minimum length is 3.</param>
/// <returns>The random string.</returns>
public string RandomString(int length)
{
    length = Math.Max(length, 3);

    byte[] bytes = new byte[length];
    _rand.NextBytes(bytes);
    return Convert.ToBase64String(bytes).Substring(0, length);
}
2
répondu AechoLiu 2013-06-25 07:17:22

je pense que c'est peut-être aussi acceptable et simple.

Guid.NewGuid().ToString() 
2
répondu wener 2013-10-29 07:34:27

si vous voulez générer une chaîne de nombres et de caractères pour un mot de passe fort.

private static Random random = new Random();

private static string CreateTempPass(int size)
        {
            var pass = new StringBuilder();
            for (var i=0; i < size; i++)
            {
                var binary = random.Next(0,2);
                switch (binary)
                {
                    case 0:
                    var ch = (Convert.ToChar(Convert.ToInt32(Math.Floor(26*random.NextDouble() + 65))));
                        pass.Append(ch);
                        break;
                    case 1:
                        var num = random.Next(1, 10);
                        pass.Append(num);
                        break;
                }
            }
            return pass.ToString();
        }
1
répondu CGsoldier 2010-10-14 21:38:29

combinant la réponse par "Pushcode" et celle utilisant la graine pour le générateur aléatoire. J'en avais besoin pour créer une série de pseudo-lisible "mots".

private int RandomNumber(int min, int max, int seed=0)
{
    Random random = new Random((int)DateTime.Now.Ticks + seed);
    return random.Next(min, max);
}
1
répondu Ideogram 2012-01-04 06:29:43

j'ai créé cette méthode.

ça marche très bien.

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

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

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

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

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

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

            //Random the NonAlphaNumericChars
            for (i = Lenght - NonAlphaNumericChars; i < Lenght; 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[Lenght];
            for (i = 0; i < Lenght; i++)
                sorted[i] = pass[pos[i]];

            string Pass = new String(sorted);

            return Pass;
    }
1
répondu Hugo 2012-05-15 12:04:56

et voici une autre idée basée sur des devinettes. Je l'ai utilisé pour le Visual Studio performance test pour générer une chaîne de caractères aléatoire ne contenant que des caractères alphanumériques.

public string GenerateRandomString(int stringLength)
{
    Random rnd = new Random();
    Guid guid;
    String randomString = string.Empty;

    int numberOfGuidsRequired = (int)Math.Ceiling((double)stringLength / 32d);
    for (int i = 0; i < numberOfGuidsRequired; i++)
    {
        guid = Guid.NewGuid();
        randomString += guid.ToString().Replace("-", "");
    }

    return randomString.Substring(0, stringLength);
}
1
répondu Maciej Zaleski 2012-06-19 10:48:55

voici un billet de blog qui fournit une classe un peu plus robuste pour générer des mots, des phrases et des paragraphes aléatoires.

1
répondu Nick Olsen 2012-06-21 08:15:39
public static class StringHelpers
{
    public static readonly Random rnd = new Random();

    public static readonly string EnglishAlphabet = "abcdefghijklmnopqrstuvwxyz";
    public static readonly string RussianAlphabet = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";

    public static unsafe string GenerateRandomUTF8String(int length, string alphabet)
    {
        if (length <= 0)
            return String.Empty;
        if (string.IsNullOrWhiteSpace(alphabet))
            throw new ArgumentNullException("alphabet");

        byte[] randomBytes = rnd.NextBytes(length);

        string s = new string(alphabet[0], length);

        fixed (char* p = s)
        {
            for (int i = 0; i < s.Length; i++)
            {
                *(p + i) = alphabet[randomBytes[i] % alphabet.Length];
            }
        }
        return s;
    }

    public static unsafe string GenerateRandomUTF8String(int length, params UnicodeCategory[] unicodeCategories)
    {
        if (length <= 0)
            return String.Empty;
        if (unicodeCategories == null)
            throw new ArgumentNullException("unicodeCategories");
        if (unicodeCategories.Length == 0)
            return rnd.NextString(length);

        byte[] randomBytes = rnd.NextBytes(length);

        string s = randomBytes.ConvertToString();
        fixed (char* p = s)
        {
            for (int i = 0; i < s.Length; i++)
            {
                while (!unicodeCategories.Contains(char.GetUnicodeCategory(*(p + i))))
                    *(p + i) += (char)*(p + i);
            }
        }
        return s;
    }
}

vous aurez aussi besoin de ceci:

public static class RandomExtensions
{
    public static string NextString(this Random rnd, int length)
    {
        if (length <= 0)
            return String.Empty;

        return rnd.NextBytes(length).ConvertToString();
    }

    public static byte[] NextBytes(this Random rnd, int length)
    {
        if (length <= 0)
            return new byte[0];

        byte[] randomBytes = new byte[length];
        rnd.NextBytes(randomBytes);
        return randomBytes;
    }
}

et ceci:

public static class ByteArrayExtensions
{
    public static string ConvertToString(this byte[] bytes)
    {
        if (bytes.Length <= 0)
            return string.Empty;

        char[] chars = new char[bytes.Length / sizeof(char)];
        Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }
}
1
répondu Konard 2013-04-18 10:29:10

en fait, une bonne solution est d'avoir une méthode statique pour le générateur de nombres aléatoires qui est thread-safe et n'utilise pas de serrures.

de cette façon, les utilisateurs multiples accédant à votre application web en même temps ne reçoivent pas les mêmes chaînes aléatoires.

il y a 3 exemples ici: http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx

j'utiliserais le dernier:

public static class RandomGen3
{
    private static RNGCryptoServiceProvider _global = 
        new RNGCryptoServiceProvider();
    [ThreadStatic]
    private static Random _local;

    public static int Next()
    {
        Random inst = _local;
        if (inst == null)
        {
            byte[] buffer = new byte[4];
            _global.GetBytes(buffer);
            _local = inst = new Random(
                BitConverter.ToInt32(buffer, 0));
        }
        return inst.Next();
    }
}

alors vous pouvez correctement éliminer

Random random = new Random();

et appelez simplement RandomGen3.Next (), alors que votre méthode peut rester statique.

1
répondu Stefan Steiger 2013-05-23 11:04:28

pour générateur de chaîne aléatoire:

#region CREATE RANDOM STRING WORD
        char[] wrandom = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','R','S','T','U','V','X','W','Y','Z'};
        Random random = new Random();
        string random_string = "";
        int count = 12; //YOU WILL SPECIFY HOW MANY CHARACTER WILL BE GENERATE
        for (int i = 0; i < count; i++ )
        {
            random_string = random_string + wrandom[random.Next(0, 24)].ToString(); 
        }
        MessageBox.Show(random_string);
        #endregion
1
répondu Toprak 2014-01-02 12:47:31

j'ai trouvé cela plus utile, car c'est une extension, et cela vous permet de sélectionner la source de votre code.

static string
    numbers = "0123456789",
    letters = "abcdefghijklmnopqrstvwxyz",
    lettersUp = letters.ToUpper(),
    codeAll = numbers + letters + lettersUp;

static Random m_rand = new Random();

public static string GenerateCode(this int size)
{
    return size.GenerateCode(CodeGeneratorType.All);
}

public static string GenerateCode(this int size, CodeGeneratorType type)
{
    string source;

    if (type == CodeGeneratorType.All)
    {
        source = codeAll;
    }
    else
    {
        StringBuilder sourceBuilder = new StringBuilder();
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Numbers)
            sourceBuilder.Append(numbers);
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Letters)
            sourceBuilder.Append(letters);
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.LettersUpperCase)
            sourceBuilder.Append(lettersUp);

        source = sourceBuilder.ToString();
    }

    return size.GenerateCode(source);
}

public static string GenerateCode(this int size, string source)
{
    StringBuilder code = new StringBuilder();
    int maxIndex = source.Length-1;
    for (int i = 0; i < size; i++)
    {

        code.Append(source[Convert.ToInt32(Math.Round(m_rand.NextDouble() * maxIndex))]);
    }

    return code.ToString();
}

public enum CodeGeneratorType { Numbers = 1, Letters = 2, LettersUpperCase = 4, All = 16 };

Espérons que cette aide.

0
répondu WhyMe 2013-04-07 18:22:17

dans ma situation, le mot de passe doit contenir:

  • au moins un minuscule.
  • Au moins une majuscule.
  • Au moins une décimale.
  • Au moins un caractère spécial.

Voici mon code:

    private string CreatePassword(int len)
    {
        string[] valid = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "1234567890", "!@#$%^&*()_+" };
        RNGCryptoServiceProvider rndGen = new RNGCryptoServiceProvider();

        byte[] random = new byte[len];
        int[] selected = new int[len];

        do
        {
            rndGen.GetNonZeroBytes(random);

            for (int i = 0; i < random.Length; i++)
            {
                selected[i] = random[i] % 4;
            }
        } 
        while(selected.Distinct().Count() != 4);

        rndGen.GetNonZeroBytes(random);

        string res = "";

        for(int i = 0; i<len; i++)
        {
            res += valid[selected[i]][random[i] % valid[selected[i]].Length];
        }
        return res;
    }
0
répondu Jules 2013-12-12 00:03:58

Hello

vous pouvez utiliser Motgenerator ou LoremIpsumGenerator de MMLib.Rapidprototyping nuget package.

using MMLib.RapidPrototyping.Generators;
public void WordGeneratorExample()
{
   WordGenerator generator = new WordGenerator();
   var randomWord = generator.Next();

   Console.WriteLine(randomWord);
} 

site du Nuget

site du projet Codeplex

0
répondu Mino 2013-12-30 10:36:51

si vous avez accès à un processeur compatible Intel, vous pouvez générer des nombres aléatoires réels et des chaînes en utilisant ces bibliothèques: https://github.com/JebteK/RdRand et https://www.rdrand.com /

il suffit de télécharger la dernière version de ici , inclure Jebtek.RdRand et les ajouter à l'aide d'instruction. Ensuite, tout ce que vous devez faire est ceci:

bool isAvailable = RdRandom.GeneratorAvailable(); //Check to see if this is a compatible CPU
string key = RdRandom.GenerateKey(10); //Generate 10 random characters

Plus, vous obtenez également ces capacités supplémentaires:

string apiKey = RdRandom.GenerateAPIKey(); //Generate 64 random characters, useful for API keys
byte[] b = RdRandom.GenerateBytes(10); //Generate an array of 10 random bytes
uint i = RdRandom.GenerateUnsignedInt() //Generate a random unsigned int

si vous n'avez pas de CPU compatible pour exécuter le code sur, utilisez simplement les services RESTful à rdrand.com. Avec la bibliothèque rdrandom wrapper incluse dans votre projet, vous aurez juste besoin de le faire (vous recevez 1000 appels gratuits lorsque vous vous inscrivez):

string ret = Randomizer.GenerateKey(<length>, "<key>");

vous pouvez également générer des tableaux d'octets aléatoires et des entiers non signés comme suit:

uint ret = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
0
répondu JebaDaHut 2014-04-05 20:39:16

un autre échantillon (testé en vs2013):

    Random R = new Random();
    public static string GetRandomString(int Length)
    {
        char[] ArrRandomChar = new char[Length];
        for (int i = 0; i < Length; i++)
            ArrRandomChar[i] = (char)('a' + R.Next(0, 26));
        return new string(ArrRandomChar);
    }

    string D = GetRandomString(12);

mis en œuvre par moi-même.

0
répondu Amin Ghaderi 2014-05-27 16:13:02

C'est ma solution:

private string RandomString(int length)
{
    char[] symbols = { 
                            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                            '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',
                            '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'                             
                        };

    Stack<byte> bytes = new Stack<byte>();
    string output = string.Empty;

    for (int i = 0; i < length; i++)
    {
        if (bytes.Count == 0)
        {
            bytes = new Stack<byte>(Guid.NewGuid().ToByteArray());
        }
        byte pop = bytes.Pop();
        output += symbols[(int)pop % symbols.Length];
    }
    return output;
}

// get 1st random string 
string Rand1 = RandomString(4);

// get 2nd random string 
string Rand2 = RandomString(4);

// create full rand string
string docNum = Rand1 + "-" + Rand2;
0
répondu ADM-IT 2016-01-13 12:29:09