Skip to content

Commit 6908af5

Browse files
committed
Seeded deterministic UUID generation test
1 parent 8c4fa3f commit 6908af5

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

Tests/FoundationEssentialsTests/UUIDTests.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,22 @@ private struct UUIDTests {
133133
XCTAssertEqual(uuid.varint, 0b10)
134134
}
135135
}
136+
137+
func testDeterministicRandomGeneration() {
138+
var generator = PCGRandomNumberGenerator(seed: 123456789)
139+
140+
let firstUUID = UUID.random(using: &generator)
141+
XCTAssertEqual(firstUUID, UUID(uuidString: "9492BAC4-F353-49E7-ACBB-A40941CA65DE"))
142+
143+
let secondUUID = UUID.random(using: &generator)
144+
XCTAssertEqual(secondUUID, UUID(uuidString: "392C44E5-EB3E-4455-85A7-AF9556722B9A"))
145+
146+
let thirdUUID = UUID.random(using: &generator)
147+
XCTAssertEqual(thirdUUID, UUID(uuidString: "9ABFCCE9-AA85-485C-9CBF-C62F0C8D1D1A"))
148+
149+
let fourthUUID = UUID.random(using: &generator)
150+
XCTAssertEqual(fourthUUID, UUID(uuidString: "2B29542E-F719-4D58-87B9-C6291ADD4541"))
151+
}
136152
}
137153

138154
extension UUID {
@@ -144,3 +160,28 @@ extension UUID {
144160
Int(self.uuid.8 >> 6 & 0b11)
145161
}
146162
}
163+
164+
fileprivate struct PCGRandomNumberGenerator: RandomNumberGenerator {
165+
private static let multiplier: UInt128 = 47_026_247_687_942_121_848_144_207_491_837_523_525
166+
private static let increment: UInt128 = 117_397_592_171_526_113_268_558_934_119_004_209_487
167+
168+
private var state: UInt128
169+
170+
fileprivate init(seed: UInt64) {
171+
self.state = UInt128(seed)
172+
}
173+
174+
fileprivate mutating func next() -> UInt64 {
175+
self.state = self.state &* Self.multiplier &+ Self.increment
176+
177+
return rotr64(
178+
value: UInt64(truncatingIfNeeded: self.state &>> 64) ^ UInt64(truncatingIfNeeded: self.state),
179+
rotation: UInt64(truncatingIfNeeded: self.state &>> 122)
180+
)
181+
}
182+
183+
private func rotr64(value: UInt64, rotation: UInt64) -> UInt64 {
184+
(value &>> rotation) | value &<< ((~rotation &+ 1) & 63)
185+
}
186+
}
187+

0 commit comments

Comments
 (0)