[C#] Generating a String of Random Digits

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
I'll post this here because I've posted it elsewhere. Usually people will generate the digits individually, but it means that you'll be making many more unnecessary calls to generate a digit. Here's my logic...

Code:
[NO-PARSE]private static readonly Random rnd = new Random();[/NO-PARSE]

Code:
[NO-PARSE]static void GenDigits(int len, ref string result)
{
	if (result == null) throw new ArgumentNullException("result");
	int j = 0;
	do
	{
		int diff = len - j;
		bool more = diff > 9;
		result +=
			rnd.Next(more ? 1000000000 : (int) Math.Pow(10, diff))
				.ToString(more ? "000000000" : new string('0', diff));
	} while ((j += 9) < len);
}[/NO-PARSE]

Basically, since Random.Next() returns an integer, unless we use a function that has a return value of a larger datatype, like a 64 bit integer, instead of a 32 bit integer. We can generate a value consisting of all 9's as digits, as high as 9 digits in length (999,999,999), without exceeding the 32 bit integer max value. Why all 9's? Because if we went all the way up to the max, the first digit in that random generation would only have possible values of 1 and 2, omitting from 3-9, and excluding 0, unless you were to pad the rest of the length with 0's (which we will do).

You could generate values that differ by an exponent of 1, when it comes to powers of 10, for the min and max, to avoid the possibility of many 0's as padding, I just didn't bother.

Because we can generate up to 9 digits at a time. A string of 25 digits in length would only take 3 subsequent calls to the Random.Next() function; 9 + 9 + 7 == 25. Which is much more effective than 25 separate calls and a concatenation for each digit to the resulting string.

Here is some test code you can use:
Code:
[NO-PARSE]string s = string.Empty;
for (int i = 1; i < 25; i++)
{
	GenDigits(i, ref s);
	Console.WriteLine("{0:00} :: {1} [{2}]", s.Length, s.Length == i, s);
	s = string.Empty;
}[/NO-PARSE]

For larger string's, of course you may want to opt to replace traditional string concatenation here, with a StringBuilder instance as well instead.

For getting random generation's with an unsigned long to further improve this implementation, you may want to also look at my earlier thread about a special P/Invoke'd function, here: Quick Random Generation

Just showing you that outside of the box thinking can improve code just as much as using the proper types and strategies when programming. But I've also not posted a thread like this in a while.

Demo output:
cL8Omj0.png


:thumbsup2:
 
Last edited:
That's a pretty ingenious idea ace.

As any skilled programmer knows, the algorithm is more important than any implementation and this is such a wonderful example.
 
Function calls take time, this is something most people overlook. But not only calling the function, but if the function has to instantiate a whole bunch of objects locally before doing any calculations, this is also an overhead. Obviously you can see where calling a function less times, but allowing it to work with larger chunks of data at a time, is more efficient and effective. It just takes a train of thought to start thinking about things like this. Good or great programmers, don't only just know how to code, they know how to allow the code to be more efficient for what they want it to do, by an understanding of how things in their code work on a deep level.

It is fun stretching the boundaries and limitations of .NET though. :) I write redundant throw-away code all the time. It's not just about coding, it's about playing around.
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top