9

I've an already method to generate a random string. But it's slow. I wanna improve the method using regular expression which I'm not good at.

My code:

public string GetRandomString()
{
   var random = new Random();
   string id = new string(Enumerable.Repeat("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 16)
              .Select(s => s[random.Next(s.Length)]).ToArray());
   return id;
}

By using regex, I can compress the string: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 to some characters easily. Just like:

var regex = new Regex(@"[\w\d]{16}");

Is there a way to create a random string with the regex?

4 Answers 4

16

You can try the following library for generating random string from pattern: https://github.com/moodmosaic/Fare

var xeger = new Xeger(pattern);
var generatedString = xeger.Generate();

Secondly, why do you generate string using Enumerate.Repeat? Why don't you save it in string or cache it? What is the point to repeat it 16 times? I think you generate this string each method call and that's why it's slow. To my mind string interning doesn't work in your code because of code generated string. How about doing it this way:

string dictionaryString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuilder resultStringBuilder = new StringBuilder();
for (int i=0;i<desiredLength;i++)
{
    resultStringBuilder.Append(dictionaryString[random.Next(dictionary.Length)]);
}
return resultStringBuilder.ToString();
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks! I think it's a way to do everything in 1 line. But I'm really getting slow with it. That's the reason I wanna convert it to regex. I will try again with your advice.
Actually, I did something very similar to make some fake GUIDs. The performance was terrible (not using Enumerate.Repeat logic). I was actually pretty surprised.
Oh, please wait. What's desiredLength?
this is a desired random string length. I don't know what you need some number or random number.
One thing I have noticed with Fare is that if I attempt to generate a list of 100 strings, randomness is very weak. I created a hashset with a limit of 100 entries. I generated the values in a for loop, and out of that 100 limit, only 26 were actually unique. Just a heads up, in case randomness is important in a scenario where you may need a list/array of values.
|
1

I've tried this before, and the performance wasn't that great. Regex is one way to do it. I'm all for regex, but using it in this sense is over-engineering.

Make an array with all the characters you want to use, and then randomly cycle through it grabbing a single element at a time (or a group with element displacement) and you should be good to go.

Here's a sample program you can copypasta or peruse. I'd be very interested to know the performance difference between @Access Denied's answer, and this little guy. Pardon the lack of elegance, but I was going to clarity in case someone else stumbles upon this.

using System;
using System.Text;

namespace RandomString
{
    class Program
    {

        static void Main()
        {
            Console.WriteLine("My new random alphanumeric string is {0}", GetRandomAlphaNumString(12));
            Console.WriteLine("\nPress any key to exit...");
            Console.ReadKey(true);
        }

        static char[] charactersAvailable = {'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',
                                             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

        public static string GetRandomAlphaNumString(uint stringLength)
        {
            StringBuilder randomString = new StringBuilder();

            Random randomCharacter = new Random();

            for (uint i = 0; i < stringLength; i++)
            {
                int randomCharSelected = randomCharacter.Next(0, (charactersAvailable.Length - 1));

                randomString.Append(charactersAvailable[randomCharSelected]);
            }

            return randomString.ToString();
        }
    }
}

13 Comments

Thanks! Sound like making random index/position of elements in an array.
Wow. I've written another method like yours. It's working. You can edit the array to charactersAvailable = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray(). It's faster. Thank you!
Yeah. All kinds of ways to optimize this sample. This one just uses regular old System, and no other fun stuff, with long var/method names. Elegant code rocks, but I try to keep most answers readable to newbie coders. Let me know which answer performs better when you're done!
I understand you mean ^^! The method's faster, not fastest.
Don't do that randomString +=. Concat works slow. Use StringBuilder for that purposes. You create lots of strings in memory.
|
1

I find that the easiest way to generate a random string based on the Regex pattern is to use the RandomDataGenerator.Net NuGet package. You can find it on GitHub: https://github.com/StefH/RandomDataGenerator

So in your case the code will look like:

using RandomDataGenerator.FieldOptions;
using RandomDataGenerator.Randomizers;

public string GetRandomString(string pattern)
{
    if (string.IsNullOrEmpty(pattern))
    {
        throw new ArgumentException("Regex pattern cannot be null or empty.", nameof(pattern));
    }

    var randomizerTextRegex = RandomizerFactory.GetRandomizer(new FieldOptionsTextRegex { Pattern = pattern });

    return randomizerTextRegex.Generate();
}

And use it like:

var regexPattern = "^[a-zA-Z0-9]{16}";
var randonString = GetRandomString(regexPattern);

Comments

0

This always generates a random string, Though its just some small modification on the above mentioned code snippet.

    static char[] charactersAvailable = {'A', '3', '4', 'D', 'E', 'f', 'g', 'h', '5', '6', 'i', 'j', 'k', 'l', 'm', 'n', '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', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                                         '0', '1', '2', '7', '8', '9', 'B', 'C'};

    public static string GetRandomAlphaNumString(int stringLength)
    {
        StringBuilder randomString = new StringBuilder();
        randomString.Clear();
        for (int i = 0; i < stringLength; i++)
        { 
            string str = GetCurrentTime().Ticks.ToString();
            int randomCharSelected = Convert.ToInt32(str.Substring(16, 1));

            randomString.Append(charactersAvailable[randomCharSelected]);
        }

        return randomString.ToString();
    }
    internal static DateTime GetCurrentTime()
    {
        Thread.Sleep(1);
            DateTime result = DateTime.UtcNow;
            return result;
    }
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.