Dart language offers Random class to generate a random result of boolean, int, and double value. The usage is very simple. Let’s have a look.
Basic usage of Random
Random class has 3 methods.
nextBool();
nextInt(int max);
nextDouble();
Just call one of them after instantiating an instance.
final random = new Random();
for (var i = 0; i < loopCount; i++) {
final boolValue = random.nextBool();
final intValue = random.nextInt(100);
final doubleValue = random.nextDouble();
print("$boolValue\t$intValue\t$doubleValue");
}
// Bool Int Double
// ----------------------------------------
// false 47 0.8030808978673076
// false 2 0.3018160608691639
// true 45 0.9991493833440004
// false 88 0.414774595519641
// false 99 0.23824450531447028
// true 33 0.29656709090965194
// false 85 0.9747426076875625
// false 5 0.44814308497889466
// false 35 0.7952298650841252
// false 1 0.6126148790736863
The constructor has an optional argument called seed
. If we pass an int number here, it always generates the same set of results. See the following example. The new instance is created in the for a loop. The result is always the same.
for (var i = 0; i < loopCount; i++) {
print(Random(2).nextInt(100));
}
// 73
// 73
// 73
// 73
// 73
// 73
// 73
// 73
// 73
// 73
Be careful if you want to give a seed.
Generate random value for Cryptography
If you want to generate random value for Cryptography, a normal constructor shouldn’t be used. It offers a different constructor Random.secure()
. To generate a random value, it must be random, unpredictable, and irreproducible. If the seed can be predictable, the value can also be predictable.
Check the specification of the random generator if you need to generate it for Cryptography.
final secure = Random.secure();
for (var i = 0; i < loopCount; i++) {
print(secure.nextInt(100));
}
// 6
// 26
// 45
// 55
// 45
// 89
// 51
// 66
// 0
// 80
Random int number in range
If we need to generate random values in a range, we need to add small logic. It looks like this.
final min = 30;
final max = 100;
for (var i = 0; i < loopCount; i++) {
print(min + random.nextInt(max - min));
}
In this case above, max – min is 70. Therefore, random.nextInt(70);
can be 0 – 70. We want at least 30, its min value needs to be added.
Random double number in range
I tried some ways. Come to the point, this way is the simplest.
double _generateDouble2(double minValue, double maxValue, int precision) {
final random = new Random();
final doubleRandom = minValue + (maxValue - minValue) * random.nextDouble();
return double.parse(doubleRandom.toStringAsFixed(precision));
}
for (var i = 0; i < loopCount; i++) {
final value = _generateDouble2(4.1, 10.432, 4);
print("$value");
}
// 6.6825
// 7.683
// 10.016
// 6.3594
// 4.4341
// 4.5369
// 6.4781
// 8.2649
// 7.8907
// 4.2494
Basically, it’s the same logic as the int version. nextDouble
doesn’t have any arguments, we have to add the logic there. I used the combination of double.parse
and toStringAsFixed
to get a precise number. If we want to have 3 digits after the decimal point, we somehow need to cut the rest.
The first way that I tried to get a random double number in the range 0 – 10 with 2 digits after the decimal point is as follows.
for (var i = 0; i < loopCount; i++) {
print(random.nextInt(1000) * 0.01);
}
// 9.84
// 5.47
// 1.56
// 8.97
// 0.8
// 9.450000000000001
// 1.19
// 7.8
// 0.42
// 3.2800000000000002
The value sometimes gets crazy because of the way of calculation.
The next way is as follows but it can’t control the value after the decimal point.
for (var i = 0; i < loopCount; i++) {
double value = random.nextDouble() * 10;
value = double.parse(value.toStringAsFixed(2));
print(value);
}
// 8.83
// 9.0
// 3.2
// 0.37
// 9.55
// 4.46
// 5.1
// 9.16
// 8.13
// 6.11
The last way is tricky. No one wants to apply this logic.
double _generateDouble(double minValue, double maxValue, int precision) {
final minValues = minValue.toString().split(".");
final maxValues = maxValue.toString().split(".");
final maxLengthAfterDecimalPoint = max(
minValues[1].length,
maxValues[1].length,
);
// e.g. min 5.51, max 11.234
// --> 5510 , 11234
final intMin = minValue * pow(10, maxLengthAfterDecimalPoint);
final intMax = maxValue * pow(10, maxLengthAfterDecimalPoint);
final random = new Random();
final intRandom =
intMin.toInt() + random.nextInt(intMax.toInt() - intMin.toInt());
final doubleRandom = intRandom * pow(0.1, maxLengthAfterDecimalPoint);
return double.parse(doubleRandom.toStringAsFixed(precision));
}
for (var i = 0; i < loopCount + 40; i++) {
final value = _generateDouble(5.51, 11.234, 3);
print("$value");
}
// 7.488
// 7.968
// 9.73
// 7.836
// 9.543
// 8.483
// 6.805
// 7.607
// 10.991
// 8.222
Comments