उत्पन्न करना मैं सुरक्षित रूप से श्रेणी [0, एन) में यादृच्छिक संख्या उत्पन्न करना चाहता हूं, जहां एन पैरामीटर है। हालांकि, System.Security.Cryptography.RandomNumberGenerator केवल यादृच्छिक मानों के साथ सरणी भरने के लिए GetBytes() विधि प्रदान करता है।सुरक्षित रूप से एक समान यादृच्छिक BigInteger
(मैं SRP का एक थोड़ा संशोधित संस्करण में प्रयोग किया जाता nonces के लिए यादृच्छिक पूर्णांकों की जरूरत है। "थोड़ा संशोधित" भाग मेरे नियंत्रण से बाहर है, और एकमात्र कारण मैं भी छू क्रिप्टो सामान कर रहा हूँ।)
मैंने ऐसा करने के लिए एक विधि लिखी है, लेकिन मैं एक बेहतर तरीका ढूंढ रहा हूं या कम से कम पुष्टि कर रहा हूं कि मैं इसे सही कर रहा हूं।
using System.Numerics
///<summary>Generates a uniformly random integer in the range [0, bound).</summary>
public static BigInteger RandomIntegerBelow(this System.Security.Cryptography.RandomNumberGenerator source, BigInteger bound) {
Contract.Requires<ArgumentException>(source != null);
Contract.Requires<ArgumentException>(bound > 0);
Contract.Ensures(Contract.Result<BigInteger>() >= 0);
Contract.Ensures(Contract.Result<BigInteger>() < bound);
//Get a byte buffer capable of holding any value below the bound
var buffer = (bound << 16).ToByteArray(); // << 16 adds two bytes, which decrease the chance of a retry later on
//Compute where the last partial fragment starts, in order to retry if we end up in it
var generatedValueBound = BigInteger.One << (buffer.Length * 8 - 1); //-1 accounts for the sign bit
Contract.Assert(generatedValueBound >= bound);
var validityBound = generatedValueBound - generatedValueBound % bound;
Contract.Assert(validityBound >= bound);
while (true) {
//generate a uniformly random value in [0, 2^(buffer.Length * 8 - 1))
source.GetBytes(buffer);
buffer[buffer.Length - 1] &= 0x7F; //force sign bit to positive
var r = new BigInteger(buffer);
//return unless in the partial fragment
if (r >= validityBound) continue;
return r % bound;
}
}
यह कुछ सुंदर कोड है। – Amy