c# - मैं सी#में यादृच्छिक अल्फान्यूमेरिक स्ट्रिंग कैसे उत्पन्न कर सकता हूं?




.net random (20)

मैं सी # में यादृच्छिक 8 वर्ण अल्फान्यूमेरिक स्ट्रिंग कैसे उत्पन्न कर सकता हूं?


इस धागे में विभिन्न उत्तरों के कुछ प्रदर्शन तुलना:

तरीके और सेटअप

// what's available
public static string possibleChars = "abcdefghijklmnopqrstuvwxyz";
// optimized (?) what's available
public static char[] possibleCharsArray = possibleChars.ToCharArray();
// optimized (precalculated) count
public static int possibleCharsAvailable = possibleChars.Length;
// shared randomization thingy
public static Random random = new Random();


// http://.com/a/1344242/1037948
public string LinqIsTheNewBlack(int num) {
    return new string(
    Enumerable.Repeat(possibleCharsArray, num)
              .Select(s => s[random.Next(s.Length)])
              .ToArray());
}

// http://.com/a/1344258/1037948
public string ForLoop(int num) {
    var result = new char[num];
    while(num-- > 0) {
        result[num] = possibleCharsArray[random.Next(possibleCharsAvailable)];
    }
    return new string(result);
}

public string ForLoopNonOptimized(int num) {
    var result = new char[num];
    while(num-- > 0) {
        result[num] = possibleChars[random.Next(possibleChars.Length)];
    }
    return new string(result);
}

public string Repeat(int num) {
    return new string(new char[num].Select(o => possibleCharsArray[random.Next(possibleCharsAvailable)]).ToArray());
}

// http://.com/a/1518495/1037948
public string GenerateRandomString(int num) {
  var rBytes = new byte[num];
  random.NextBytes(rBytes);
  var rName = new char[num];
  while(num-- > 0)
    rName[num] = possibleCharsArray[rBytes[num] % possibleCharsAvailable];
  return new string(rName);
}

//SecureFastRandom - or SolidSwiftRandom
static string GenerateRandomString(int Length) //Configurable output string length
{
    byte[] rBytes = new byte[Length]; 
    char[] rName = new char[Length];
    SolidSwiftRandom.GetNextBytesWithMax(rBytes, biasZone);
    for (var i = 0; i < Length; i++)
    {
        rName[i] = charSet[rBytes[i] % charSet.Length];
    }
    return new string(rName);
}

परिणाम

लिंककैड में परीक्षण किया गया। 10 के स्ट्रिंग आकार के लिए, उत्पन्न करता है:

  • लिंक = chdgmevhcy से [10]
  • लूप = gtnoaryhxr से [10]
  • चयन = rsndbztyby से [10]
  • GenerateRandomString = owyefjjakj से [10]
  • SecureFastRandom = VzougLYHYP से [10]
  • SecureFastRandom-NoCache = oVQXNGmO1S से [10]

और प्रदर्शन संख्या थोड़ा भिन्न होती है, कभी-कभी NonOptimized - NonOptimized वास्तव में तेज़ होती है, और कभी-कभी ForLoop और ForLoop स्विच जो लीड में है।

  • LinqIsTheNewBlack (10000x) = 96762 ticks elapsed (9.6762 एमएस)
  • फॉर लूप (10000x) = 28 9 70 टिक निकल गए (2.897 एमएस)
  • ForLoopNonOptimized (10000x) = 33336 ticks elapsed (3.3336 एमएस)
  • दोहराना (10000x) = 78547 टिक निकल गया (7.8547 एमएस)
  • जेनरेट रैंडमस्ट्रिंग (10000x) = 27416 टिक निकल गई (2.7416 एमएस)
  • सिक्योरफास्टरैंडम (10000x) = 13176 टिक निकलता है (5 एमएमएस) सबसे कम [अलग मशीन]
  • SecureFastRandom-NoCache (10000x) = 39541 टिक निकलती है (17 मिमी) सबसे कम [अलग मशीन]

एक और विकल्प एक स्ट्रिंगबिल्डर में लिंक और कुल यादृच्छिक वर्णों का उपयोग करना हो सकता है।

var chars = "abcdefghijklmnopqrstuvwxyz123456789".ToArray();
string pw = Enumerable.Range(0, passwordLength)
                      .Aggregate(
                          new StringBuilder(),
                          (sb, n) => sb.Append((chars[random.Next(chars.Length)])),
                          sb => sb.ToString());

एरिक जे द्वारा लिखित कोड काफी मैला है (यह काफी स्पष्ट है कि यह 6 साल पहले से है ... वह शायद आज उस कोड को नहीं लिख पाएगा), और यहां तक ​​कि कुछ समस्याएं भी हैं।

प्रस्तुत विकल्पों में से कुछ के विपरीत, यह क्रिप्टोग्राफ़िक रूप से ध्वनि है।

असत्य ... पासवर्ड में एक पूर्वाग्रह है (जैसा कि एक टिप्पणी में लिखा गया है), bcdefgh दूसरों की तुलना में थोड़ा अधिक संभावित है (ऐसा नहीं है क्योंकि GetNonZeroBytes द्वारा यह शून्य के मान के साथ बाइट उत्पन्न नहीं कर रहा है, इसलिए एक के लिए पूर्वाग्रह इसके द्वारा संतुलित है), इसलिए यह वास्तव में क्रिप्टोग्राफिक ध्वनि नहीं है।

यह सभी समस्याओं को सही करना चाहिए।

public static string GetUniqueKey(int size = 6, string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
{
    using (var crypto = new RNGCryptoServiceProvider())
    {
        var data = new byte[size];

        // If chars.Length isn't a power of 2 then there is a bias if
        // we simply use the modulus operator. The first characters of
        // chars will be more probable than the last ones.

        // buffer used if we encounter an unusable random byte. We will
        // regenerate it in this buffer
        byte[] smallBuffer = null;

        // Maximum random number that can be used without introducing a
        // bias
        int maxRandom = byte.MaxValue - ((byte.MaxValue + 1) % chars.Length);

        crypto.GetBytes(data);

        var result = new char[size];

        for (int i = 0; i < size; i++)
        {
            byte v = data[i];

            while (v > maxRandom)
            {
                if (smallBuffer == null)
                {
                    smallBuffer = new byte[1];
                }

                crypto.GetBytes(smallBuffer);
                v = smallBuffer[0];
            }

            result[i] = chars[v % chars.Length];
        }

        return new string(result);
    }
}

डीटीबी के समाधान का थोड़ा क्लीनर संस्करण।

    var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    var random = new Random();
    var list = Enumerable.Repeat(0, 8).Select(x=>chars[random.Next(chars.Length)]);
    return string.Join("", list);

आपकी शैली प्राथमिकताएं भिन्न हो सकती हैं।


भयानक, मुझे पता है, लेकिन मैं सिर्फ खुद की मदद नहीं कर सका:


namespace ConsoleApplication2
{
    using System;
    using System.Text.RegularExpressions;

    class Program
    {
        static void Main(string[] args)
        {
            Random adomRng = new Random();
            string rndString = string.Empty;
            char c;

            for (int i = 0; i < 8; i++)
            {
                while (!Regex.IsMatch((c=Convert.ToChar(adomRng.Next(48,128))).ToString(), "[A-Za-z0-9]"));
                rndString += c;
            }

            Console.WriteLine(rndString + Environment.NewLine);
        }
    }
}


मेरा सरल एक लाइन कोड मेरे लिए काम करता है :)

string  random = string.Join("", Guid.NewGuid().ToString("n").Take(8).Select(o => o));

Response.Write(random.ToUpper());
Response.Write(random.ToLower());

किसी भी लंबाई स्ट्रिंग के लिए इस पर विस्तार करने के लिए

    public static string RandomString(int length)
    {
        //length = length < 0 ? length * -1 : length;
        var str = "";

        do 
        {
            str += Guid.NewGuid().ToString().Replace("-", "");
        }

        while (length > str.Length);

        return str.Substring(0, length);
    }

मैं एक और विशिष्ट उत्तर की तलाश में था, जहां मैं यादृच्छिक स्ट्रिंग के प्रारूप को नियंत्रित करना चाहता हूं और इस पोस्ट में आया हूं। उदाहरण के लिए: लाइसेंस प्लेट्स (कारों के) में एक विशिष्ट प्रारूप (प्रति देश) है और मैं यादृच्छिक लाइसेंस प्लेट बनाना चाहता था।
मैंने इसके लिए रैंडम की अपनी विस्तार विधि लिखने का फैसला किया। (यह वही रैंडम ऑब्जेक्ट का पुन: उपयोग करने के लिए है, क्योंकि आप बहु-थ्रेडिंग परिदृश्यों में युगल हो सकते हैं)। मैंने एक गिस्ट बनाया ( https://gist.github.com/SamVanhoutte/808845ca78b9c041e928 ), लेकिन यहां एक्सटेंशन क्लास की प्रतिलिपि भी बनाई जाएगी:

void Main()
{
    Random rnd = new Random();
    rnd.GetString("1-###-000").Dump();
}

public static class RandomExtensions
{
    public static string GetString(this Random random, string format)
    {
        // Based on http://.com/questions/1344221/how-can-i-generate-random-alphanumeric-strings-in-c
        // Added logic to specify the format of the random string (# will be random string, 0 will be random numeric, other characters remain)
        StringBuilder result = new StringBuilder();
        for(int formatIndex = 0; formatIndex < format.Length ; formatIndex++)
        {
            switch(format.ToUpper()[formatIndex])
            {
                case '0': result.Append(getRandomNumeric(random)); break;
                case '#': result.Append(getRandomCharacter(random)); break;
                default : result.Append(format[formatIndex]); break;
            }
        }
        return result.ToString();
    }

    private static char getRandomCharacter(Random random)
    {
        string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        return chars[random.Next(chars.Length)];
    }

    private static char getRandomNumeric(Random random)
    {
        string nums = "0123456789";
        return nums[random.Next(nums.Length)];
    }
}

मैंने सुना है कि LINQ नया काला है, इसलिए LINQ का उपयोग करके मेरा प्रयास यहां है:

private static Random random = new Random();
public static string RandomString(int length)
{
    const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    return new string(Enumerable.Repeat(chars, length)
      .Select(s => s[random.Next(s.Length)]).ToArray());
}

( नोट: रैंडम क्लास का उपयोग किसी भी सुरक्षा से संबंधित, जैसे पासवर्ड या टोकन बनाने के लिए अनुपयुक्त बनाता है।
यदि आपको एक मजबूत यादृच्छिक संख्या जनरेटर की आवश्यकता है तो RNGCryptoServiceProvider क्लास का उपयोग करें।)


यह कार्यान्वयन (गूगल के माध्यम से पाया गया) मुझे लगता है।

प्रस्तुत विकल्पों में से कुछ के विपरीत, यह क्रिप्टोग्राफ़िक रूप से ध्वनि है

using System.Security.Cryptography;
using System.Text;

namespace UniqueKey
{
    public class KeyGenerator
    {
        public static string GetUniqueKey(int maxSize)
        {
            char[] chars = new char[62];
            chars =
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
            byte[] data = new byte[1];
            using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider())
            {
                crypto.GetNonZeroBytes(data);
                data = new byte[maxSize];
                crypto.GetNonZeroBytes(data);
            }
            StringBuilder result = new StringBuilder(maxSize);
            foreach (byte b in data)
            {
                result.Append(chars[b % (chars.Length)]);
            }
            return result.ToString();
        }
    }
}

here विकल्पों के बारे में चर्चा से एक चुना


यहां एक उदाहरण दिया गया है कि मैंने डॉट नेट पर्ल्स पर सैम एलन उदाहरण से चुरा लिया

अगर आपको केवल 8 वर्णों की आवश्यकता है, तो System.IO नामस्थान में Path.GetRandomFileName () का उपयोग करें। सैम का कहना है कि "Path.GetRandomFileName विधि का उपयोग कभी-कभी बेहतर होता है, क्योंकि यह बेहतर यादृच्छिकता के लिए RNGCryptoServiceProvider का उपयोग करता है। हालांकि, यह 11 यादृच्छिक वर्णों तक सीमित है।"

GetRandomFileName हमेशा 9वीं वर्ण की अवधि के साथ एक 12 वर्ण स्ट्रिंग देता है। तो आपको अवधि को पट्टी करने की आवश्यकता होगी (क्योंकि यह यादृच्छिक नहीं है) और फिर स्ट्रिंग से 8 वर्ण लें। असल में, आप केवल पहले 8 अक्षर ले सकते हैं और इस अवधि के बारे में चिंता नहीं कर सकते हैं।

public string Get8CharacterRandomString()
{
    string path = Path.GetRandomFileName();
    path = path.Replace(".", ""); // Remove period.
    return path.Substring(0, 8);  // Return 8 character string
}

पीएस: धन्यवाद सैम


हम कस्टम स्ट्रिंग यादृच्छिक का भी उपयोग करते हैं लेकिन हमने कार्यान्वित एक स्ट्रिंग के सहायक के रूप में किया है, इसलिए यह कुछ लचीलापन प्रदान करता है ...

public static string Random(this string chars, int length = 8)
{
    var randomString = new StringBuilder();
    var random = new Random();

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

    return randomString.ToString();
}

प्रयोग

var random = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Random();

या

var random = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".Random(16);

प्रश्न: मुझे "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789" Enumerable.Range "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789" टाइप करने के बजाय Enumerable.Range का उपयोग करके अपना समय बर्बाद क्यों करना चाहिए?

using System;
using System.Collections.Generic;
using System.Linq;

public class Test
{
    public static void Main()
    {
        var randomCharacters = GetRandomCharacters(8, true);
        Console.WriteLine(new string(randomCharacters.ToArray()));
    }

    private static List<char> getAvailableRandomCharacters(bool includeLowerCase)
    {
        var integers = Enumerable.Empty<int>();
        integers = integers.Concat(Enumerable.Range('A', 26));
        integers = integers.Concat(Enumerable.Range('0', 10));

        if ( includeLowerCase )
            integers = integers.Concat(Enumerable.Range('a', 26));

        return integers.Select(i => (char)i).ToList();
    }

    public static IEnumerable<char> GetRandomCharacters(int count, bool includeLowerCase)
    {
        var characters = getAvailableRandomCharacters(includeLowerCase);
        var random = new Random();
        var result = Enumerable.Range(0, count)
            .Select(_ => characters[random.Next(characters.Count)]);

        return result;
    }
}

उत्तर: जादू तार बीएडी हैं। क्या किसी ने नोटिस किया कि शीर्ष पर मेरी स्ट्रिंग में कोई " I " नहीं था? मेरी मां ने मुझे इस कारण से जादू तारों का उपयोग नहीं करना सिखाया ...

एनबी 1: @ डीटीबी जैसे कई अन्य लोगों ने कहा, सिस्टम का उपयोग न करें। यादृच्छिक अगर आपको क्रिप्टोग्राफिक सुरक्षा की आवश्यकता है ...

एनबी 2: यह उत्तर सबसे कुशल या छोटा नहीं है, लेकिन मैं चाहता था कि अंतरिक्ष प्रश्न से उत्तर को अलग करे। मेरे जवाब का उद्देश्य एक फैंसी अभिनव उत्तर प्रदान करने के बजाय जादू तारों के खिलाफ चेतावनी देना अधिक है।


A solution without using Random :

var chars = Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 8);

var randomStr = new string(chars.SelectMany(str => str)
                                .OrderBy(c => Guid.NewGuid())
                                .Take(8).ToArray());

After reviewing the other answers and considering CodeInChaos' comments, along with CodeInChaos still biased (although less) answer, I thought a final ultimate cut and paste solution was needed. So while updating my answer I decided to go all out.

For an up to date version of this code, please visit the new Hg repository on Bitbucket: https://bitbucket.org/merarischroeder/secureswiftrandom . I recommend you copy and paste the code from: https://bitbucket.org/merarischroeder/secureswiftrandom/src/6c14b874f34a3f6576b0213379ecdf0ffc7496ea/Code/Alivate.SolidSwiftRandom/SolidSwiftRandom.cs?at=default&fileviewer=file-view-default (make sure you click the Raw button to make it easier to copy and make sure you have the latest version, I think this link goes to a specific version of the code, not the latest).

Updated notes:

  1. Relating to some other answers - If you know the length of the output, you don't need a StringBuilder, and when using ToCharArray, this creates and fills the array (you don't need to create an empty array first)
  2. Relating to some other answers - You should use NextBytes, rather than getting one at a time for performance
  3. Technically you could pin the byte array for faster access.. it's usually worth it when your iterating more than 6-8 times over a byte array. (Not done here)
  4. Use of RNGCryptoServiceProvider for best randomness
  5. Use of caching of a 1MB buffer of random data - benchmarking shows cached single bytes access speed is ~1000x faster - taking 9ms over 1MB vs 989ms for uncached.
  6. Optimised rejection of bias zone within my new class.

End solution to question:

static char[] charSet =  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray();
static int byteSize = 256; //Labelling convenience
static int biasZone = byteSize - (byteSize % charSet.Length);
public string GenerateRandomString(int Length) //Configurable output string length
{
    byte[] rBytes = new byte[Length]; //Do as much before and after lock as possible
    char[] rName = new char[Length];
    SecureFastRandom.GetNextBytesMax(rBytes, biasZone);
    for (var i = 0; i < Length; i++)
    {
        rName[i] = charSet[rBytes[i] % charSet.Length];
    }
    return new string(rName);
}

But you need my new (untested) class:

/// <summary>
/// My benchmarking showed that for RNGCryptoServiceProvider:
/// 1. There is negligable benefit of sharing RNGCryptoServiceProvider object reference 
/// 2. Initial GetBytes takes 2ms, and an initial read of 1MB takes 3ms (starting to rise, but still negligable)
/// 2. Cached is ~1000x faster for single byte at a time - taking 9ms over 1MB vs 989ms for uncached
/// </summary>
class SecureFastRandom
{
    static byte[] byteCache = new byte[1000000]; //My benchmark showed that an initial read takes 2ms, and an initial read of this size takes 3ms (starting to raise)
    static int lastPosition = 0;
    static int remaining = 0;

    /// <summary>
    /// Static direct uncached access to the RNGCryptoServiceProvider GetBytes function
    /// </summary>
    /// <param name="buffer"></param>
    public static void DirectGetBytes(byte[] buffer)
    {
        using (var r = new RNGCryptoServiceProvider())
        {
            r.GetBytes(buffer);
        }
    }

    /// <summary>
    /// Main expected method to be called by user. Underlying random data is cached from RNGCryptoServiceProvider for best performance
    /// </summary>
    /// <param name="buffer"></param>
    public static void GetBytes(byte[] buffer)
    {
        if (buffer.Length > byteCache.Length)
        {
            DirectGetBytes(buffer);
            return;
        }

        lock (byteCache)
        {
            if (buffer.Length > remaining)
            {
                DirectGetBytes(byteCache);
                lastPosition = 0;
                remaining = byteCache.Length;
            }

            Buffer.BlockCopy(byteCache, lastPosition, buffer, 0, buffer.Length);
            lastPosition += buffer.Length;
            remaining -= buffer.Length;
        }
    }

    /// <summary>
    /// Return a single byte from the cache of random data.
    /// </summary>
    /// <returns></returns>
    public static byte GetByte()
    {
        lock (byteCache)
        {
            return UnsafeGetByte();
        }
    }

    /// <summary>
    /// Shared with public GetByte and GetBytesWithMax, and not locked to reduce lock/unlocking in loops. Must be called within lock of byteCache.
    /// </summary>
    /// <returns></returns>
    static byte UnsafeGetByte()
    {
        if (1 > remaining)
        {
            DirectGetBytes(byteCache);
            lastPosition = 0;
            remaining = byteCache.Length;
        }

        lastPosition++;
        remaining--;
        return byteCache[lastPosition - 1];
    }

    /// <summary>
    /// Rejects bytes which are equal to or greater than max. This is useful for ensuring there is no bias when you are modulating with a non power of 2 number.
    /// </summary>
    /// <param name="buffer"></param>
    /// <param name="max"></param>
    public static void GetBytesWithMax(byte[] buffer, byte max)
    {
        if (buffer.Length > byteCache.Length / 2) //No point caching for larger sizes
        {
            DirectGetBytes(buffer);

            lock (byteCache)
            {
                UnsafeCheckBytesMax(buffer, max);
            }
        }
        else
        {
            lock (byteCache)
            {
                if (buffer.Length > remaining) //Recache if not enough remaining, discarding remaining - too much work to join two blocks
                    DirectGetBytes(byteCache);

                Buffer.BlockCopy(byteCache, lastPosition, buffer, 0, buffer.Length);
                lastPosition += buffer.Length;
                remaining -= buffer.Length;

                UnsafeCheckBytesMax(buffer, max);
            }
        }
    }

    /// <summary>
    /// Checks buffer for bytes equal and above max. Must be called within lock of byteCache.
    /// </summary>
    /// <param name="buffer"></param>
    /// <param name="max"></param>
    static void UnsafeCheckBytesMax(byte[] buffer, byte max)
    {
        for (int i = 0; i < buffer.Length; i++)
        {
            while (buffer[i] >= max)
                buffer[i] = UnsafeGetByte(); //Replace all bytes which are equal or above max
        }
    }
}

For history - my older solution for this answer, used Random object:

    private static char[] charSet =
      "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray();

    static rGen = new Random(); //Must share, because the clock seed only has Ticks (~10ms) resolution, yet lock has only 20-50ns delay.
    static int byteSize = 256; //Labelling convenience
    static int biasZone = byteSize - (byteSize % charSet.Length);
    static bool SlightlyMoreSecurityNeeded = true; //Configuration - needs to be true, if more security is desired and if charSet.Length is not divisible by 2^X.
    public string GenerateRandomString(int Length) //Configurable output string length
    {
      byte[] rBytes = new byte[Length]; //Do as much before and after lock as possible
      char[] rName = new char[Length];
      lock (rGen) //~20-50ns
      {
          rGen.NextBytes(rBytes);

          for (int i = 0; i < Length; i++)
          {
              while (SlightlyMoreSecurityNeeded && rBytes[i] >= biasZone) //Secure against 1/5 increased bias of index[0-7] values against others. Note: Must exclude where it == biasZone (that is >=), otherwise there's still a bias on index 0.
                  rBytes[i] = rGen.NextByte();
              rName[i] = charSet[rBytes[i] % charSet.Length];
          }
      }
      return new string(rName);
    }

Performance:

  1. SecureFastRandom - First single run = ~9-33ms . Imperceptible. Ongoing : 5ms (sometimes it goes up to 13ms) over 10,000 iterations, With a single average iteration= 1.5 microseconds. । Note: Requires generally 2, but occasionally up to 8 cache refreshes - depends on how many single bytes exceed the bias zone
  2. Random - First single run = ~0-1ms . Imperceptible. Ongoing : 5ms over 10,000 iterations. With a single average iteration= .5 microseconds. । About the same speed.

Here is a variant of Eric J's solution, ie cryptographically sound, for WinRT (Windows Store App):

public static string GenerateRandomString(int length)
{
    var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    var result = new StringBuilder(length);
    for (int i = 0; i < length; ++i)
    {
        result.Append(CryptographicBuffer.GenerateRandomNumber() % chars.Length);
    }
    return result.ToString();
}

If performance matters (especially when length is high):

public static string GenerateRandomString(int length)
{
    var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    var result = new System.Text.StringBuilder(length);
    var bytes = CryptographicBuffer.GenerateRandom((uint)length * 4).ToArray();
    for (int i = 0; i < bytes.Length; i += 4)
    {
        result.Append(BitConverter.ToUInt32(bytes, i) % chars.Length);
    }
    return result.ToString();
}

I don't know how cryptographically sound this is, but it's more readable and concise than the more intricate solutions by far (imo), and it should be more "random" than System.Random -based solutions.

return alphabet
    .OrderBy(c => Guid.NewGuid())
    .Take(strLength)
    .Aggregate(
        new StringBuilder(),
        (builder, c) => builder.Append(c))
    .ToString();

I can't decide if I think this version or the next one is "prettier", but they give the exact same results:

return new string(alphabet
    .OrderBy(o => Guid.NewGuid())
    .Take(strLength)
    .ToArray());

Granted, it isn't optimized for speed, so if it's mission critical to generate millions of random strings every second, try another one!

NOTE: This solution doesn't allow for repetitions of symbols in the alphabet, and the alphabet MUST be of equal or greater size than the output string, making this approach less desirable in some circumstances, it all depends on your use-case.


If your values are not completely random, but in fact may depend on something - you may compute an md5 or sha1 hash of that 'somwthing' and then truncate it to whatever length you want.

Also you may generate and truncate a guid.


Now in one-liner flavour.

private string RandomName
    {
        get
        {
            return new string(
                Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 13)
                    .Select(s =>
                    {
                        var cryptoResult = new byte[4];
                        new RNGCryptoServiceProvider().GetBytes(cryptoResult);
                        return s[new Random(BitConverter.ToInt32(cryptoResult, 0)).Next(s.Length)];
                    })
                    .ToArray());
        }
    }

 public static string RandomString(int length)
    {
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        var random = new Random();
        return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
    }

public static class StringHelper
{
    private static readonly Random random = new Random();

    private const int randomSymbolsDefaultCount = 8;
    private const string availableChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    private static int randomSymbolsIndex = 0;

    public static string GetRandomSymbols()
    {
        return GetRandomSymbols(randomSymbolsDefaultCount);
    }

    public static string GetRandomSymbols(int count)
    {
        var index = randomSymbolsIndex;
        var result = new string(
            Enumerable.Repeat(availableChars, count)
                      .Select(s => {
                          index += random.Next(s.Length);
                          if (index >= s.Length)
                              index -= s.Length;
                          return s[index];
                      })
                      .ToArray());
        randomSymbolsIndex = index;
        return result;
    }
}







random