@@ -124,6 +124,22 @@ final class UUIDTests : XCTestCase {
124
124
XCTAssertEqual ( uuid. varint, 0b10 )
125
125
}
126
126
}
127
+
128
+ func testDeterministicRandomGeneration( ) {
129
+ var generator = PCGRandomNumberGenerator ( seed: 123456789 )
130
+
131
+ let firstUUID = UUID . random ( using: & generator)
132
+ XCTAssertEqual ( firstUUID, UUID ( uuidString: " 9492BAC4-F353-49E7-ACBB-A40941CA65DE " ) )
133
+
134
+ let secondUUID = UUID . random ( using: & generator)
135
+ XCTAssertEqual ( secondUUID, UUID ( uuidString: " 392C44E5-EB3E-4455-85A7-AF9556722B9A " ) )
136
+
137
+ let thirdUUID = UUID . random ( using: & generator)
138
+ XCTAssertEqual ( thirdUUID, UUID ( uuidString: " 9ABFCCE9-AA85-485C-9CBF-C62F0C8D1D1A " ) )
139
+
140
+ let fourthUUID = UUID . random ( using: & generator)
141
+ XCTAssertEqual ( fourthUUID, UUID ( uuidString: " 2B29542E-F719-4D58-87B9-C6291ADD4541 " ) )
142
+ }
127
143
}
128
144
129
145
extension UUID {
@@ -135,3 +151,28 @@ extension UUID {
135
151
Int ( self . uuid. 8 >> 6 & 0b11 )
136
152
}
137
153
}
154
+
155
+ fileprivate struct PCGRandomNumberGenerator : RandomNumberGenerator {
156
+ private static let multiplier : UInt128 = 47_026_247_687_942_121_848_144_207_491_837_523_525
157
+ private static let increment : UInt128 = 117_397_592_171_526_113_268_558_934_119_004_209_487
158
+
159
+ private var state : UInt128
160
+
161
+ fileprivate init ( seed: UInt64 ) {
162
+ self . state = UInt128 ( seed)
163
+ }
164
+
165
+ fileprivate mutating func next( ) -> UInt64 {
166
+ self . state = self . state &* Self . multiplier &+ Self . increment
167
+
168
+ return rotr64 (
169
+ value: UInt64 ( truncatingIfNeeded: self . state &>> 64 ) ^ UInt64 ( truncatingIfNeeded: self . state) ,
170
+ rotation: UInt64 ( truncatingIfNeeded: self . state &>> 122 )
171
+ )
172
+ }
173
+
174
+ private func rotr64( value: UInt64 , rotation: UInt64 ) -> UInt64 {
175
+ ( value &>> rotation) | value &<< ( ( ~ rotation &+ 1 ) & 63 )
176
+ }
177
+ }
178
+
0 commit comments