Skip to content

Commit ffde843

Browse files
committed
Seeded deterministic UUID generation test
1 parent d9ffe2f commit ffde843

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

Tests/FoundationEssentialsTests/UUIDTests.swift

+41
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,22 @@ final class UUIDTests : XCTestCase {
124124
XCTAssertEqual(uuid.varint, 0b10)
125125
}
126126
}
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+
}
127143
}
128144

129145
extension UUID {
@@ -135,3 +151,28 @@ extension UUID {
135151
Int(self.uuid.8 >> 6 & 0b11)
136152
}
137153
}
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

Comments
 (0)