Работа криптографически стойкого генератора случайных чисел
Генерация 1000000
от 1 до 6
void DemonstrateSecureRandomness()
{
int totalIterations = 1000000;
int minValue = 1;
int maxValue = 6;
int[] counts = new int[maxValue - minValue + 1];
project.SendInfoToLog($"Генерируем {totalIterations} случайных чисел от {minValue} до {maxValue}");
for (int i = 0; i < totalIterations; i++)
{
int randomNumber = GenerateSecureRandomNumber(minValue, maxValue);
counts[randomNumber - minValue]++;
if (i < 20 || i > totalIterations - 20)
{
project.SendInfoToLog($"Итерация {i + 1}: Сгенерировано число {randomNumber}");
}
else if (i == 20)
{
project.SendInfoToLog("...");
}
}
project.SendInfoToLog("\nРезультаты:");
for (int i = 0; i < counts.Length; i++)
{
double percentage = (double)counts[i] / totalIterations * 100;
project.SendInfoToLog($"Число {i + minValue}: {counts[i]} раз ({percentage:F2}%)");
}
double expectedPercentage = 100.0 / (maxValue - minValue + 1);
double maxDeviation = 0;
for (int i = 0; i < counts.Length; i++)
{
double deviation = System.Math.Abs((double)counts[i] / totalIterations * 100 - expectedPercentage);
if (deviation > maxDeviation)
{
maxDeviation = deviation;
}
}
project.SendInfoToLog($"\nМаксимальное отклонение от ожидаемого значения: {maxDeviation:F2}%");
if (maxDeviation < 1)
{
project.SendInfoToLog("Распределение очень близко к равномерному", true);
}
else if (maxDeviation < 2)
{
project.SendInfoToLog("Распределение близко к равномерному", true);
}
else
{
project.SendInfoToLog("Распределение может быть неравномерным", false);
}
double chiSquare = 0;
for (int i = 0; i < counts.Length; i++)
{
double expected = expectedPercentage * totalIterations / 100;
chiSquare += System.Math.Pow(counts[i] - expected, 2) / expected;
}
project.SendInfoToLog($"\nЗначение хи-квадрат: {chiSquare:F4}");
project.SendInfoToLog("Для 3 степеней свободы и уровня значимости 0.05, критическое значение хи-квадрат равно 7.815");
if (chiSquare < 7.815)
{
project.SendInfoToLog("Распределение статистически равномерно", true);
}
else
{
project.SendInfoToLog("Распределение статистически неравномерно", false);
}
}
int GenerateSecureRandomNumber(int minValue, int maxValue)
{
if (minValue > maxValue)
throw new System.ArgumentOutOfRangeException("minValue");
if (minValue == maxValue)
return minValue;
var rng = System.Security.Cryptography.RandomNumberGenerator.Create();
long range = (long)maxValue - minValue + 1;
byte[] uint32Buffer = new byte[4];
while (true)
{
rng.GetBytes(uint32Buffer);
uint randomUInt = System.BitConverter.ToUInt32(uint32Buffer, 0);
long result = (long)(randomUInt % range);
if (randomUInt - result + (range - 1) >= randomUInt)
{
return (int)(minValue + result);
}
}
}
// Вызов функции демонстрации
DemonstrateSecureRandomness();
Результат:
Число 1: 166676 раз (16,67%)
Число 2: 166640 раз (16,66%)
Число 3: 166721 раз (16,67%)
Число 4: 166828 раз (16,68%)
Число 5: 166382 раз (16,64%)
Число 6: 166753 раз (16,68%)
Максимальное отклонение от ожидаемого значения: 0,03%
Значение хи-квадрат: 0,7096
Для 3 степеней свободы и уровня значимости 0.05, критическое значение хи-квадрат равно 7.815
Распределение статистически равномерно