Add random.org for random number generation.

This commit is contained in:
runebaas 2020-09-23 16:05:43 +02:00
parent b743539c74
commit ae9b9caeb9
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
6 changed files with 62 additions and 12 deletions

View file

@ -11,6 +11,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Anemonis.RandomOrg" Version="1.14.0" />
<PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="Discord.Net" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0-rc.1.*" />

View file

@ -1,25 +1,69 @@
using System;
using System.Security.Cryptography;
using Anemonis.RandomOrg;
using Geekbot.Core.GlobalSettings;
namespace Geekbot.Core.RandomNumberGenerator
{
public class RandomNumberGenerator : IRandomNumberGenerator
{
readonly RNGCryptoServiceProvider csp;
private readonly RNGCryptoServiceProvider csp;
private readonly bool _canUseRandomOrg;
private readonly RandomOrgClient _randomOrgClient;
public RandomNumberGenerator()
public RandomNumberGenerator(IGlobalSettings globalSettings)
{
csp = new RNGCryptoServiceProvider();
var randomOrgApiKey = globalSettings.GetKey("RandomOrgApiKey");
if (!string.IsNullOrEmpty(randomOrgApiKey))
{
_canUseRandomOrg = true;
_randomOrgClient = new RandomOrgClient(randomOrgApiKey);
}
}
public int Next(int minValue, int maxExclusiveValue)
public int Next(int minValue, int maxInclusiveValue)
{
if (minValue >= maxExclusiveValue)
if (minValue == maxInclusiveValue)
{
return maxInclusiveValue;
}
if (minValue >= maxInclusiveValue)
{
throw new ArgumentOutOfRangeException("minValue must be lower than maxExclusiveValue");
}
if (_canUseRandomOrg)
{
try
{
return GetFromRandomOrg(minValue, maxInclusiveValue);
}
catch
{
// ignore
}
}
var diff = (long)maxExclusiveValue - minValue;
return GetFromCrypto(minValue, maxInclusiveValue);
}
private int GetFromRandomOrg(int minValue, int maxInclusiveValue)
{
return _randomOrgClient
.GenerateIntegersAsync(1, minValue, maxInclusiveValue, false)
.Result
.Random
.Data[0];
}
private int GetFromCrypto(int minValue, int maxInclusiveValue)
{
var maxExclusiveValue = maxInclusiveValue + 1;
var diff = (long) maxExclusiveValue - minValue;
var upperBound = uint.MaxValue / diff * diff;
uint ui;
@ -27,7 +71,8 @@ namespace Geekbot.Core.RandomNumberGenerator
{
ui = GetRandomUInt();
} while (ui >= upperBound);
return (int)(minValue + (ui % diff));
return (int) (minValue + (ui % diff));
}
private uint GetRandomUInt()