1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using Xunit;
6 
7 namespace System.Tests
8 {
9     public static partial class RandomTests
10     {
11         [Fact]
Unseeded()12         public static void Unseeded()
13         {
14             Random r = new Random();
15             for (int i = 0; i < 1000; i++)
16             {
17                 int x = r.Next(20);
18                 Assert.True(x >= 0 && x < 20);
19             }
20             for (int i = 0; i < 1000; i++)
21             {
22                 int x = r.Next(20, 30);
23                 Assert.True(x >= 20 && x < 30);
24             }
25             for (int i = 0; i < 1000; i++)
26             {
27                 double x = r.NextDouble();
28                 Assert.True(x >= 0.0 && x < 1.0);
29             }
30         }
31 
32         [Fact]
Seeded()33         public static void Seeded()
34         {
35             int seed = Environment.TickCount;
36 
37             Random r1 = new Random(seed);
38             Random r2 = new Random(seed);
39 
40             byte[] b1 = new byte[1000];
41             r1.NextBytes(b1);
42             byte[] b2 = new byte[1000];
43             r2.NextBytes(b2);
44             for (int i = 0; i < b1.Length; i++)
45             {
46                 Assert.Equal(b1[i], b2[i]);
47             }
48             for (int i = 0; i < b1.Length; i++)
49             {
50                 int x1 = r1.Next();
51                 int x2 = r2.Next();
52                 Assert.Equal(x1, x2);
53             }
54         }
55 
56         // Random has a predictable sequence of values it generates based on its seed.
57         // So that we'll be made aware if a change to the implementation causes these
58         // sequences to change, this test verifies the first few numbers for a few seeds.
Values()59         private static int[][] Values()
60         {
61             var expectedValues = new int[][]
62             {
63                 new int[] {1559595546, 1755192844, 1649316166, 1198642031, 442452829, 1200195957, 1945678308, 949569752, 2099272109, 587775847},
64                 new int[] {534011718, 237820880, 1002897798, 1657007234, 1412011072, 929393559, 760389092, 2026928803, 217468053, 1379662799},
65                 new int[] {1655911537, 867932563, 356479430, 2115372437, 234085668, 658591161, 1722583523, 956804207, 483147644, 24066104},
66                 new int[] {630327709, 1498044246, 1857544709, 426253993, 1203643911, 387788763, 537294307, 2034163258, 748827235, 815953056},
67                 new int[] {1752227528, 2128155929, 1211126341, 884619196, 25718507, 116986365, 1499488738, 964038662, 1014506826, 1607840008},
68                 new int[] {726643700, 610783965, 564707973, 1342984399, 995276750, 1993667614, 314199522, 2041397713, 1280186417, 252243313},
69                 new int[] {1848543519, 1240895648, 2065773252, 1801349602, 1964834993, 1722865216, 1276393953, 971273117, 1545866008, 1044130265},
70                 new int[] {822959691, 1871007331, 1419354884, 112231158, 786909589, 1452062818, 91104737, 2048632168, 1811545599, 1836017217},
71                 new int[] {1944859510, 353635367, 772936516, 570596361, 1756467832, 1181260420, 1053299168, 978507572, 2077225190, 480420522},
72                 new int[] {919275682, 983747050, 126518148, 1028961564, 578542428, 910458022, 2015493599, 2055866623, 195421134, 1272307474},
73                 new int[] {2041175501, 1613858733, 1627583427, 1487326767, 1548100671, 639655624, 830204383, 985742027, 461100725, 2064194426},
74                 new int[] {1015591673, 96486769, 981165059, 1945691970, 370175267, 368853226, 1792398814, 2063101078, 726780316, 708597731},
75                 new int[] {2137491492, 726598452, 334746691, 256573526, 1339733510, 98050828, 607109598, 992976482, 992459907, 1500484683},
76                 new int[] {1111907664, 1356710135, 1835811970, 714938729, 161808106, 1974732077, 1569304029, 2070335533, 1258139498, 144887988},
77                 new int[] {86323836, 1986821818, 1189393602, 1173303932, 1131366349, 1703929679, 384014813, 1000210937, 1523819089, 936774940},
78                 new int[] {1208223655, 469449854, 542975234, 1631669135, 2100924592, 1433127281, 1346209244, 2077569988, 1789498680, 1728661892},
79                 new int[] {182639827, 1099561537, 2044040513, 2090034338, 922999188, 1162324883, 160920028, 1007445392, 2055178271, 373065197},
80                 new int[] {1304539646, 1729673220, 1397622145, 400915894, 1892557431, 891522485, 1123114459, 2084804443, 173374215, 1164952149},
81                 new int[] {278955818, 212301256, 751203777, 859281097, 714632027, 620720087, 2085308890, 1014679847, 439053806, 1956839101},
82                 new int[] {1400855637, 842412939, 104785409, 1317646300, 1684190270, 349917689, 900019674, 2092038898, 704733397, 601242406},
83             };
84             return (expectedValues);
85         }
86 
87         [Fact]
ExpectedValues()88         public static void ExpectedValues()
89         {
90             int[][] expectedValues = Values();
91             for (int seed = 0; seed < expectedValues.Length; seed++)
92             {
93                 var r = new Random(seed);
94                 for (int i = 0; i < expectedValues[seed].Length; i++)
95                 {
96                     Assert.Equal(expectedValues[seed][i], r.Next());
97                 }
98             }
99         }
100 
ByteValues()101         private static byte[][] ByteValues()
102         {
103             var expectedValues = new byte[][]
104             {
105                 new byte[] { 0x1A, 0xC, 0x46, 0x6F, 0x5D, 0x75, 0xE4, 0xD8, 0xAD, 0x67 },
106                 new byte[] { 0x46, 0xD0, 0x86, 0x82, 0x40, 0x97, 0xE4, 0xA3, 0x95, 0xCF },
107                 new byte[] { 0x71, 0x93, 0xC6, 0x95, 0x24, 0xB9, 0xE3, 0x6F, 0x7C, 0x38 },
108                 new byte[] { 0x9D, 0x56, 0x5, 0xA9, 0x7, 0xDB, 0xE3, 0x3A, 0x63, 0xA0 },
109                 new byte[] { 0xC8, 0x19, 0x45, 0xBC, 0xEB, 0xFD, 0xE2, 0x6, 0x4A, 0x8 },
110                 new byte[] { 0xF4, 0xDD, 0x85, 0xCF, 0xCE, 0x1E, 0xE2, 0xD1, 0x31, 0x71 },
111                 new byte[] { 0x1F, 0xA0, 0xC4, 0xE2, 0xB1, 0x40, 0xE1, 0x9D, 0x18, 0xD9 },
112                 new byte[] { 0x4B, 0x63, 0x4, 0xF6, 0x95, 0x62, 0xE1, 0x68, 0xFF, 0x41 },
113                 new byte[] { 0x76, 0x27, 0x44, 0x9, 0x78, 0x84, 0xE0, 0x34, 0xE6, 0xAA },
114                 new byte[] { 0xA2, 0xEA, 0x84, 0x1C, 0x5C, 0xA6, 0xDF, 0xFF, 0xCE, 0x12 },
115                 new byte[] { 0xCD, 0xAD, 0xC3, 0x2F, 0x3F, 0xC8, 0xDF, 0xCB, 0xB5, 0x7A },
116                 new byte[] { 0xF9, 0x71, 0x3, 0x42, 0x23, 0xEA, 0xDE, 0x96, 0x9C, 0xE3 },
117                 new byte[] { 0x24, 0x34, 0x43, 0x56, 0x6, 0xC, 0xDE, 0x62, 0x83, 0x4B },
118                 new byte[] { 0x50, 0xF7, 0x82, 0x69, 0xEA, 0x2D, 0xDD, 0x2D, 0x6A, 0xB4 },
119                 new byte[] { 0x7C, 0xBA, 0xC2, 0x7C, 0xCD, 0x4F, 0xDD, 0xF9, 0x51, 0x1C },
120                 new byte[] { 0xA7, 0x7E, 0x2, 0x8F, 0xB0, 0x71, 0xDC, 0xC4, 0x38, 0x84 },
121                 new byte[] { 0xD3, 0x41, 0x41, 0xA2, 0x94, 0x93, 0xDC, 0x90, 0x1F, 0xED },
122                 new byte[] { 0xFE, 0x4, 0x81, 0xB6, 0x77, 0xB5, 0xDB, 0x5B, 0x7, 0x55 },
123                 new byte[] { 0x2A, 0xC8, 0xC1, 0xC9, 0x5B, 0xD7, 0xDA, 0x27, 0xEE, 0xBD },
124                 new byte[] { 0x55, 0x8B, 0x1, 0xDC, 0x3E, 0xF9, 0xDA, 0xF2, 0xD5, 0x26 }
125             };
126             return (expectedValues);
127         }
128 
129         [Fact]
ExpectedValues_NextBytesArray()130         public static void ExpectedValues_NextBytesArray()
131         {
132             byte[][] expectedValues = ByteValues();
133             for (int seed = 0; seed < expectedValues.Length; seed++)
134             {
135                 byte[] actualValues = new byte[expectedValues[seed].Length];
136                 var r = new Random(seed);
137                 r.NextBytes(actualValues);
138                 Assert.Equal(expectedValues[seed], actualValues);
139             }
140         }
141 
142         [Fact]
Sample()143         public static void Sample()
144         {
145             SubRandom r = new SubRandom();
146 
147             for (int i = 0; i < 1000; i++)
148             {
149                 double d = r.ExposeSample();
150                 Assert.True(d >= 0.0 && d < 1.0);
151             }
152         }
153 
154         private class SubRandom : Random
155         {
ExposeSample()156             public double ExposeSample()
157             {
158                 return Sample();
159             }
160         }
161     }
162 }
163