Generador de cadenas aleatorias que devuelve la misma cadena

Desarrollé un generador de cuerdas al azar, pero no se está comportando del todo como esperaba. Mi objective es poder ejecutar esto dos veces y generar dos cadenas aleatorias de cuatro caracteres distintas. Sin embargo, solo genera una cadena aleatoria de cuatro caracteres dos veces.

Aquí está el código y un ejemplo de su resultado:

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; 

… y la salida se ve así: UNTE-UNTE … pero debería verse algo así como UNTE-FWNU

¿Cómo puedo garantizar dos cadenas claramente aleatorias?

Está haciendo la instancia Aleatoria en el método, que hace que devuelva los mismos valores cuando se le llama en sucesión rápida. Haría algo como esto:

 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; 

(versión modificada de tu código)

Estás instanciando el objeto Random dentro de tu método.

El objeto Random se deriva del reloj del sistema , lo que significa que si llama a su método varias veces en sucesión rápida, usará la misma semilla cada vez, lo que significa que generará la misma secuencia de números aleatorios, lo que significa que obtendrás la misma cadena.

Para resolver el problema, mueva su instancia Random fuera del método en sí (y mientras lo hace, podría deshacerse de esa loca secuencia de llamadas a Convert and Floor y 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); } 

// Una implementación muy simple

 using System.IO; public static string RandomStr() { string rStr = Path.GetRandomFileName(); rStr = rStr.Replace(".", ""); // For Removing the . return rStr; } 

// Ahora solo llame al método RandomStr ()

Siempre que use Asp.Net 2.0 o superior, también puede usar la biblioteca llamada System.Web.Security.Membership.GeneratePassword , sin embargo, incluirá caracteres especiales.

Para obtener 4 caracteres aleatorios con un mínimo de 0 caracteres especiales-

 Membership.GeneratePassword(4, 0) 

Solo para que la gente se detenga y tenga una cadena aleatoria en una sola línea de código

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

PD: tenga en cuenta que yourRandomStringLength no puede exceder 32 ya que Guid tiene una longitud máxima de 32.

Otra versión del generador de cuerdas. Simple, sin cálculos de fantasía y mágicos. Pero con una cadena mágica que especifica los caracteres permitidos.

Actualización: hice el generador estático, por lo que no devolverá la misma cadena cuando se lo llame varias veces. Sin embargo, este código no es seguro para subprocesos y definitivamente no es criptográficamente seguro .

Para la generación de contraseñas se debe usar System.Security.Cryptography.RNGCryptoServiceProvider .

 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(); } 

Esta solución es una extensión para una clase Random .

Uso

 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}_-" } } 

Implementación

 public static class RandomEx { ///  /// Generates random string of printable ASCII symbols of a given length ///  /// instance of the Random class /// length of a random string /// Random string of a given length 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); } ///  /// Generates random string of printable ASCII symbols /// with random length of 10 to 20 chars ///  /// instance of the Random class /// Random string of a random length between 10 and 20 chars public static string NextString(this Random r) { int length = r.Next(10, 21); return NextString(r, length); } } 

Aquí hay una opción más:

 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()); } } 

La mejor solución es usar el generador de números aleatorios junto con la conversión de base64

 public string GenRandString(int length) { byte[] randBuffer = new byte[length]; RandomNumberGenerator.Create().GetBytes(randBuffer); return System.Convert.ToBase64String(randBuffer).Remove(length); } 

Esto se debe a que cada instancia nueva de Random está generando los mismos números que se llaman tan rápido. No sigas creando una nueva instancia, simplemente llama a next () y declara tu clase aleatoria fuera de tu método.

Un LINQ one-liner para una buena medida (suponiendo 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()); } 

Debería tener un objeto aleatorio de nivel de clase iniciado una vez en el constructor y reutilizado en cada llamada (esto continúa con la misma secuencia de números pseudoaleatorios). El constructor sin parámetros ya siembra el generador con Environment.TickCount internamente.

Agregué la opción para elegir la longitud usando la solución de 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); } } 

Aquí está mi modificación de la respuesta actualmente aceptada, que creo que es un poco más rápida y más corta:

 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(); } 

Note que no Math.floor() todas las multiplicaciones, Math.floor() , Convert etc.

EDIT: random.Next(0x41, 0x5A) se puede cambiar a cualquier rango de caracteres Unicode.

Mi método RandomString() para generar una cadena aleatoria.

 private static readonly Random _rand = new Random(); ///  /// Generate a random string. ///  /// The length of random string. The minimum length is 3. /// The random string. 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); } 

Creo que esto también es aceptable y simple.

 Guid.NewGuid().ToString() 

Si desea generar una cadena de números y caracteres para una contraseña segura.

 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(); } 

Combinando la respuesta por “Pushcode” y la que usa la semilla para el generador aleatorio. Lo necesitaba para crear una serie de ‘palabras’ pseudo-legibles.

 private int RandomNumber(int min, int max, int seed=0) { Random random = new Random((int)DateTime.Now.Ticks + seed); return random.Next(min, max); } 

Creé este método.

Funciona muy 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; } 

Y aquí hay otra idea basada en GUIDs. Lo he usado para la prueba de rendimiento de Visual Studio para generar cadenas aleatorias que contienen solo caracteres alfanuméricos.

 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); } 

Aquí hay una publicación de blog que proporciona una clase un poco más sólida para generar palabras, oraciones y párrafos aleatorios.

 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; } } 

También necesitarás esto:

 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; } } 

Y esto:

 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); } } 

En realidad, una buena solución es tener un método estático para el generador de números aleatorios que sea seguro para subprocesos y no use lockings.

De esta forma, los usuarios múltiples que acceden a su aplicación web al mismo tiempo no obtienen las mismas cadenas aleatorias.

Hay 3 ejemplos aquí: http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx

Yo usaría el último:

 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(); } } 

Entonces puedes eliminar apropiadamente

 Random random = new Random(); 

Y simplemente llame a RandomGen3.Next (), mientras que su método puede permanecer estático.

Para generador de cuerdas aleatorias:

 #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 

Me pareció más útil, ya que es una extensión, y te permite seleccionar la fuente de tu código.

 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 }; 

Espero que esto ayude.

En mi situación, la contraseña debe contener:

  • Al menos una minúscula.
  • Al menos una mayúscula.
  • Al menos un decimal.
  • Al menos un personaje especial.

Aquí está mi código:

  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 

Hola
puede usar WordGenerator o LoremIpsumGenerator del paquete nuget MMLib.RapidPrototyping.

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

Sitio de Nuget
Sitio del proyecto Codeplex

Si tiene acceso a una CPU compatible con Intel Secure Key, puede generar números aleatorios reales y cadenas utilizando estas bibliotecas: https://github.com/JebteK/RdRand y https://www.rdrand.com/

Simplemente descargue la última versión desde aquí , incluya Jebtek.RdRand y agregue una statement de uso para ello. Entonces, todo lo que necesitas hacer es esto:

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

Además, también obtiene estas capacidades adicionales:

 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 no tiene una CPU compatible para ejecutar el código, solo use los servicios RESTful en rdrand.com. Con la biblioteca contenedora RdRandom incluida en su proyecto, solo necesita hacer esto (obtiene 1000 llamadas gratuitas cuando se registra):

 string ret = Randomizer.GenerateKey(, ""); 

También puede generar matrices de bytes aleatorias y enteros sin signo de la siguiente manera:

 uint ret = Randomizer.GenerateUInt(""); byte[] ret = Randomizer.GenerateBytes(, ""); 

Otra muestra (probada 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); 

Implementado por mí mismo.

Esta es mi solución:

 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 bytes = new Stack(); string output = string.Empty; for (int i = 0; i < length; i++) { if (bytes.Count == 0) { bytes = new Stack(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;