1

I've been trying to figure out the implementation of RNGCryptoServiceProvider.GetBytes to answer the title question.

To rephrase, does the GetBytes method generate a stream/array of bits, and then just sequentially write them to the byte array, such that I could recreate the original stream/array by looping over the bytes in order and looking at the bits in each byte?

I checked the source as found here: rngcryptoserviceprovider.cs, but it calls out to the CLR apparently, and I don't know how to get the source for that.

    [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
    [ResourceExposure(ResourceScope.None)]
    private static extern void GetBytes(SafeProvHandle hProv, byte[] randomBytes, int count);
Community
  • 1
  • 1
Kal_Torak
  • 2,532
  • 1
  • 21
  • 40
  • Out of interest, why does it matter to you? – Jon Skeet Jul 20 '14 at 21:18
  • What are you trying to achieve? – Dirk Vollmar Jul 20 '14 at 21:18
  • 1
    I don't understand the question. What do you mean by "recreate"? There are no streams involved here. – usr Jul 20 '14 at 21:30
  • True, the docs talk about a sequence of (byte) values. – Dirk Vollmar Jul 20 '14 at 21:34
  • I'd like a list/stream/array of random bits. GetBytes returns bytes. I want to know if GetBytes simply returns a list of bits stored in bytes. – Kal_Torak Jul 20 '14 at 22:15
  • Ideally I'd like a hardware RNG source, such that each bit could theoretically be mapped to one "physical" event, (rather than from a seeded PRNG algorithm). Since I currently don't have such a device, I was looking into the details of .Net's RNG source. – Kal_Torak Jul 20 '14 at 22:24
  • 1
    If the bytes are random and evenly distributed, each bit should also be random and evenly distributed.. does it matter how they were generated? – Blorgbeard Jul 20 '14 at 22:25
  • @Blorgbeard, it may not matter. I'm attempting to recreate an old statistics experiment which originally used a hardware source, generating sequential bits. I simply don't know enough about statistics to know if a different type of random source will introduce unknown bias. In theory, you're right. In practice, I know statistics can have very subtle, unintuitive catches – Kal_Torak Jul 20 '14 at 22:33
  • @Kal_Torak you could use [random.org](http://random.org)? – Blorgbeard Jul 20 '14 at 22:41

1 Answers1

0

After reading the comments for more information, I think I know what you're asking...

So actually, you should use the RNGCryptoServiceProvider's GetNonZeroBytes(byte[] data) method. This will prevent you from receiving 8 zero bits in a row, which would throw off your statistical methods. Then, as blorgbeard-is-out has pointed out, "The bytes are random and evenly distributed, each bit should also be random and evenly distributed."

Also, the RNGCryptoServiceProvider can be slightly tricky to use, so I have provided a short example, along with how to convert the byte array into bits:

/* A static member inside a class somewhere. Only instantiate this once per execution of your application. */
static RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();

/* Inside a method */
byte[] rngBytes4 = new byte[4];
 _rng.GetNonZeroBytes(rngBytes4); // This populates the byte array

BitArray randomBits = new BitArray(rngBytes4);
foreach(bool bit in randomBits)
{
    // Do something with bit here
}

// And, because its not obvious how to get BitArray to return you a list: 
List<bool> randomBitsAsList = randomBits.Cast<bool>().ToList();

Adam White
  • 3,180
  • 1
  • 21
  • 18