The Labs \ Source Viewer \ SSCLI \ System.Security.Cryptography \ RNGCryptoServiceProvider

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. //
  16. // RNGCryptoServiceProvider.cs
  17. //
  18. namespace System.Security.Cryptography
  19. {
  20.     using Microsoft.Win32;
  21.     using System.Runtime.InteropServices;
  22.    
  23.     [System.Runtime.InteropServices.ComVisible(true)]
  24.     public sealed class RNGCryptoServiceProvider : RandomNumberGenerator
  25.     {
  26.        
  27.         //
  28.         // public constructors
  29.         //
  30.        
  31.         public RNGCryptoServiceProvider()
  32.         {
  33.         }
  34.        
  35.        
  36.         //
  37.         // public methods
  38.         //
  39.        
  40.         public override void GetBytes(byte[] data)
  41.         {
  42.             if (data == null)
  43.                 throw new ArgumentNullException("data");
  44.             if (!Win32Native.Random(true, data, data.Length))
  45.                 throw new CryptographicException(Marshal.GetLastWin32Error());
  46.         }
  47.        
  48.         public override void GetNonZeroBytes(byte[] data)
  49.         {
  50.             if (data == null)
  51.                 throw new ArgumentNullException("data");
  52.            
  53.             GetBytes(data);
  54.            
  55.             int indexOfFirst0Byte = data.Length;
  56.             for (int i = 0; i < data.Length; i++) {
  57.                 if (data[i] == 0) {
  58.                     indexOfFirst0Byte = i;
  59.                     break;
  60.                 }
  61.             }
  62.             for (int i = indexOfFirst0Byte; i < data.Length; i++) {
  63.                 if (data[i] != 0) {
  64.                     data[indexOfFirst0Byte++] = data[i];
  65.                 }
  66.             }
  67.            
  68.             while (indexOfFirst0Byte < data.Length) {
  69.                 // this should be more than enough to fill the rest in one iteration
  70.                 byte[] tmp = new byte[2 * (data.Length - indexOfFirst0Byte)];
  71.                 GetBytes(tmp);
  72.                
  73.                 for (int i = 0; i < tmp.Length; i++) {
  74.                     if (tmp[i] != 0) {
  75.                         data[indexOfFirst0Byte++] = tmp[i];
  76.                         if (indexOfFirst0Byte >= data.Length)
  77.                             break;
  78.                     }
  79.                 }
  80.             }
  81.         }
  82.     }
  83. }

Developer Fusion