# Algorithm to generate secure number of fixed lenght with RNGCryptoServiceProvider

#### pampua84

##### New member
Hi guys,
I'm looking for an algorithm to generate a safe random number like an OTP and I found this code on the web:

Secure Random Number Generator:
``````const int min = 100000;
const int max = 999999;
const int elemInRange = max - min + 1;

var randomData = new byte[4];

using var rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomData);
var randomInt = BitConverter.ToUInt32(randomData, 0);
var mod = randomInt % elemInRange;

var secureNumber = min + mod;``````

The problem is that I completely understand how this can generate a 6 digit number, so I'm not sure it's correct and I can use it.
Can someone kindly explain to me how this algorithm works and if it is correct to generate a 6 digit number?

Thanks a lot

#### jmcilhinney

##### C# Forum Moderator
Staff member
Have you tried to understand it? Have you read the documentation for the `RNGCryptoServiceProvider` class and its `GetBytes` method? Have you done the same for `BitConverter.ToUInt32`? Do you know what the `%` operator does? Once you understand all those things, have you stepped through the code line by line to see exactly what it does for yourself? I'm not saying that we can't or won't help but there's a lot you can do for yourself first that it doesn't look like you've done.

#### Skydiver

Staff member
Also, there's a small problem with the code presented above. Zero will never be a leading digit. So instead of of 10^6 possible values it'll be 9x10^5 values. (And yes, I've received codes with leading zeroes on both my phone authenticator as well as my RSA key fob.)

#### pampua84

##### New member
Hello,
sorry, maybe I was not very clear in asking the question, the line
C#:
``rng.GetBytes (randomData);``
fills the 8 bytes (32bit) with random values
then
C#:
``var randomInt = BitConverter.ToUInt32(randomData, 0);``
it converts those random bytes to an unsigned int,
then
C#:
``var mod = randomInt % elemInRange;``
performs the division and gives me the rest of that operation.
Now what I don't understand is: rng fills those bytes with random values, but couldn't they also be all 0s except 1?
Wouldn't that result in transforming to an int 1?
Why divide
C#:
``var mod = randomInt % elemInRange;``
?
Couldn't I exceed 6 digits by adding the min value?
I hope I have been clearer on my doubts.
Thanks

#### jmcilhinney

##### C# Forum Moderator
Staff member
maybe I was not very clear in asking the question
You weren't. If there's a section of code and you understand most of it but not one specific part then you need to specify that, because it's a waste of everyone's time for us to explain to you the parts that you already understand. Always be specific about exactly what problem you're trying to solve.

Anyway, after this:
C#:
``````const int min = 100000;
const int max = 999999;
const int elemInRange = max - min + 1;``````
the `elemInRange` constant will contain the difference between the `min` and `max` constants. This:
C#:
``var mod = randomInt % elemInRange;``
doesn't just do a division but gives you the remainder from that division. If you divide a number by `elemInRange` then the remainder will always be less than `elemInRange`. As a result, after this:
C#:
``var secureNumber = min + mod;``
`secureNumber` cannot be less than `min` and cannot be greater than `max`, i.e. it is a number in the specified range.