To generate a random alphanumeric string in C#, you can use the following methods depending on your requirements (simplicity vs. security):
1. Using Random
Class (Simple, Non-Cryptographic)
This method is suitable for general purposes where cryptographic security is not required.
using System;
using System.Linq;
public static class RandomStringGenerator
{
private static readonly Random random = new Random();
private const string Characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
public static string Generate(int length)
{
lock (random) // Ensures thread safety
{
return new string(
Enumerable.Repeat(Characters, length)
.Select(s => s[random.Next(s.Length)])
.ToArray()
);
}
}
}
Usage:
string randomString = RandomStringGenerator.Generate(10);
Console.WriteLine(randomString); // Example: "Xc3Fg9hR2T"
2. Using RandomNumberGenerator
(Secure, Cryptographic)
For security-sensitive scenarios (e.g., passwords, tokens), use cryptographically secure randomness.
using System;
using System.Security.Cryptography;
public static class SecureRandomStringGenerator
{
private const string Characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
public static string Generate(int length)
{
char[] result = new char[length];
byte[] randomBytes = new byte[length * 4]; // Buffer to avoid modulo bias
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomBytes);
}
for (int i = 0; i < length; i++)
{
// Convert 4 bytes to a UInt32 and map to the character range
uint value = BitConverter.ToUInt32(randomBytes, i * 4);
result[i] = Characters[(int)(value % (uint)Characters.Length)];
}
return new string(result);
}
}
Usage:
string secureString = SecureRandomStringGenerator.Generate(12);
Console.WriteLine(secureString); // Example: "Lk8pQw3eF7aG"
3. Using Random.Shared
(.NET 6+ for Thread Safety)
In .NET 6+, use Random.Shared
to avoid manual thread synchronization.
public static string GenerateWithSharedRandom(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
return string.Create(length, chars, (span, chars) =>
{
for (int i = 0; i < span.Length; i++)
{
span[i] = chars[Random.Shared.Next(chars.Length)];
}
});
}
Key Considerations
- Thread Safety:
Random
is not thread-safe by default. Uselock
orRandom.Shared
(.NET 6+).RandomNumberGenerator
is thread-safe.
- Performance:
- The
Random
method is faster but not secure. - The cryptographic method is slower but secure.
- Modulo Bias:
- The cryptographic method uses a buffer to reduce bias, but for strict fairness, implement rejection sampling.
- Allowed Characters:
- Adjust the
Characters
string to include/exclude specific symbols (e.g.,+=!
).
Examples
Generate a 16-character token:
// Simple method
var token1 = RandomStringGenerator.Generate(16);
// Secure method
var token2 = SecureRandomStringGenerator.Generate(16);
Exclude ambiguous characters (e.g., l
, 1
, I
):
private const string Characters = "ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
Summary
- For general use: Use
Random
with thread synchronization. - For security: Use
RandomNumberGenerator
. - For .NET 6+: Prefer
Random.Shared
for simplicity and thread safety.