How to generate a cryptographically secure Double between 0 and 1?

后端 未结 2 1337
悲哀的现实
悲哀的现实 2021-01-02 02:02

I know how to generate a random number between 0 and 1 using the NextDouble method of the pseudo-random number generator.

var rng1 = new System.Random();
var         


        
相关标签:
2条回答
  • 2021-01-02 02:13

    Well, I would not call a 64-bit random number "cryptographically secure" - you'd want a lot more bits than that to be "cryptographically secure". But anyway, you could do something like this:

    var bytes = // assume this contains 8 bytes of random numbers
    
    long l = BitConverter.ToInt64(bytes);
    double d = Math.Abs(1 / (double)l);
    
    0 讨论(0)
  • 2021-01-02 02:28

    It appears to me that the solutions so far will have uneven distribution due to taking the inverse. For an even distribution I'd think you want something like this.

    // Step 1: fill an array with 8 random bytes
    var rng = new RNGCryptoServiceProvider();
    var bytes = new Byte[8];
    rng.GetBytes(bytes);
    // Step 2: bit-shift 11 and 53 based on double's mantissa bits
    var ul = BitConverter.ToUInt64(bytes, 0) / (1 << 11);
    Double d = ul / (Double)(1UL << 53);
    

    Note that you can't just divide the UInt64 into UInt64.MaxValue, because a double doesn't have enough bits, and there's no way to get unique outputs for all your inputs. So you can/must throw some bits away.

    0 讨论(0)
提交回复
热议问题