0
# UUID Generation
1
2
## Overview
3
4
The UUID Generation capabilities provide cryptographically secure UUID creation using WASI's secure random number generation. This implementation creates Version 4 (random) UUIDs that are suitable for use as unique identifiers in distributed systems and security-sensitive applications.
5
6
## API Reference
7
8
### UUID Creation
9
10
```kotlin { .api }
11
/**
12
* UUID companion object with WASI-specific random UUID generation.
13
*/
14
@ExperimentalUuidApi
15
object Uuid.Companion {
16
/**
17
* Generates a random UUID (Version 4) using cryptographically secure random data.
18
* Uses WASI's random_get system call for entropy.
19
* @return a new random UUID
20
*/
21
@ExperimentalUuidApi
22
fun random(): Uuid
23
}
24
```
25
26
### UUID Class
27
28
```kotlin { .api }
29
/**
30
* Represents a UUID (Universally Unique Identifier).
31
*/
32
class Uuid {
33
/**
34
* The most significant 64 bits of this UUID.
35
*/
36
val mostSignificantBits: Long
37
38
/**
39
* The least significant 64 bits of this UUID.
40
*/
41
val leastSignificantBits: Long
42
43
/**
44
* Returns the string representation of this UUID.
45
* @return UUID string in standard format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
46
*/
47
override fun toString(): String
48
49
/**
50
* Compares this UUID with the specified UUID.
51
* @param other the UUID to compare with
52
* @return true if the UUIDs are equal, false otherwise
53
*/
54
override fun equals(other: Any?): Boolean
55
56
/**
57
* Returns the hash code for this UUID.
58
* @return the hash code value
59
*/
60
override fun hashCode(): Int
61
}
62
```
63
64
## Usage Examples
65
66
### Basic UUID Generation
67
68
```kotlin
69
// Generate random UUIDs
70
val uuid1 = Uuid.random()
71
val uuid2 = Uuid.random()
72
val uuid3 = Uuid.random()
73
74
println("UUID 1: $uuid1")
75
println("UUID 2: $uuid2")
76
println("UUID 3: $uuid3")
77
78
// Example output:
79
// UUID 1: f47ac10b-58cc-4372-a567-0e02b2c3d479
80
// UUID 2: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
81
// UUID 3: 886313e1-3b8a-5372-9b90-5c5fdffd6c6f
82
```
83
84
### UUID Properties
85
86
```kotlin
87
val uuid = Uuid.random()
88
89
// Access internal bits
90
val msb = uuid.mostSignificantBits
91
val lsb = uuid.leastSignificantBits
92
93
println("Most significant bits: $msb")
94
println("Least significant bits: $lsb")
95
println("String representation: $uuid")
96
97
// UUID equality and hashing
98
val uuid1 = Uuid.random()
99
val uuid2 = Uuid.random()
100
101
println("UUIDs equal: ${uuid1 == uuid2}") // false (extremely unlikely)
102
println("UUID1 hash: ${uuid1.hashCode()}")
103
println("UUID2 hash: ${uuid2.hashCode()}")
104
```
105
106
### Using UUIDs as Identifiers
107
108
```kotlin
109
// Entity identification
110
data class User(
111
val id: Uuid = Uuid.random(),
112
val name: String,
113
val email: String
114
)
115
116
val user = User(name = "Alice", email = "alice@example.com")
117
println("User ID: ${user.id}")
118
119
// Session management
120
class SessionManager {
121
private val sessions = mutableMapOf<Uuid, SessionData>()
122
123
fun createSession(userId: String): Uuid {
124
val sessionId = Uuid.random()
125
sessions[sessionId] = SessionData(userId, System.currentTimeMillis())
126
return sessionId
127
}
128
129
fun getSession(sessionId: Uuid): SessionData? {
130
return sessions[sessionId]
131
}
132
}
133
134
data class SessionData(val userId: String, val createdAt: Long)
135
```
136
137
### UUID Collections
138
139
```kotlin
140
// UUIDs as map keys
141
val userProfiles = mutableMapOf<Uuid, UserProfile>()
142
143
val userId1 = Uuid.random()
144
val userId2 = Uuid.random()
145
146
userProfiles[userId1] = UserProfile("Alice", 30)
147
userProfiles[userId2] = UserProfile("Bob", 25)
148
149
// UUIDs in sets
150
val activeUserIds = mutableSetOf<Uuid>()
151
activeUserIds.add(userId1)
152
activeUserIds.add(userId2)
153
154
println("Active users: ${activeUserIds.size}")
155
156
// UUID lists for ordered collections
157
val eventIds = mutableListOf<Uuid>()
158
repeat(5) { eventIds.add(Uuid.random()) }
159
160
eventIds.forEach { id ->
161
println("Event ID: $id")
162
}
163
```
164
165
### Request Tracing
166
167
```kotlin
168
// Distributed tracing with UUIDs
169
class RequestTracer {
170
private val traceId = Uuid.random()
171
private val spans = mutableListOf<TraceSpan>()
172
173
fun startSpan(operation: String): TraceSpan {
174
val span = TraceSpan(
175
spanId = Uuid.random(),
176
traceId = traceId,
177
operation = operation,
178
startTime = System.currentTimeMillis()
179
)
180
spans.add(span)
181
return span
182
}
183
184
fun getTrace(): TraceData {
185
return TraceData(traceId, spans.toList())
186
}
187
}
188
189
data class TraceSpan(
190
val spanId: Uuid,
191
val traceId: Uuid,
192
val operation: String,
193
val startTime: Long,
194
var endTime: Long? = null
195
)
196
197
data class TraceData(val traceId: Uuid, val spans: List<TraceSpan>)
198
199
// Usage
200
val tracer = RequestTracer()
201
val dbSpan = tracer.startSpan("database_query")
202
// ... perform database operation ...
203
dbSpan.endTime = System.currentTimeMillis()
204
205
val serviceSpan = tracer.startSpan("external_service_call")
206
// ... call external service ...
207
serviceSpan.endTime = System.currentTimeMillis()
208
209
val trace = tracer.getTrace()
210
println("Trace ID: ${trace.traceId}")
211
trace.spans.forEach { span ->
212
println(" Span: ${span.operation} (${span.spanId})")
213
}
214
```
215
216
### Database Entity IDs
217
218
```kotlin
219
// Database entity with UUID primary key
220
data class Product(
221
val id: Uuid = Uuid.random(),
222
val name: String,
223
val price: Double,
224
val categoryId: Uuid
225
) {
226
fun toMap(): Map<String, Any> = mapOf(
227
"id" to id.toString(),
228
"name" to name,
229
"price" to price,
230
"category_id" to categoryId.toString()
231
)
232
}
233
234
// Repository pattern with UUIDs
235
class ProductRepository {
236
private val products = mutableMapOf<Uuid, Product>()
237
238
fun save(product: Product): Product {
239
products[product.id] = product
240
return product
241
}
242
243
fun findById(id: Uuid): Product? {
244
return products[id]
245
}
246
247
fun findAll(): List<Product> {
248
return products.values.toList()
249
}
250
251
fun deleteById(id: Uuid): Boolean {
252
return products.remove(id) != null
253
}
254
}
255
256
// Usage
257
val repository = ProductRepository()
258
val categoryId = Uuid.random()
259
260
val product = Product(
261
name = "Laptop",
262
price = 999.99,
263
categoryId = categoryId
264
)
265
266
repository.save(product)
267
val retrieved = repository.findById(product.id)
268
println("Retrieved product: $retrieved")
269
```
270
271
## Implementation Details
272
273
### UUID Version 4 Specification
274
275
The WASI implementation generates Version 4 (random) UUIDs according to RFC 4122:
276
277
- **122 random bits**: 122 bits are randomly generated
278
- **Version bits**: 4 bits set to version 4 (0100)
279
- **Variant bits**: 2 bits set to variant 10
280
- **Format**: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where y is 8, 9, A, or B
281
282
### Cryptographic Security
283
284
UUID generation uses WASI's cryptographically secure random number generator:
285
286
```kotlin
287
// Internal implementation uses secure random bytes
288
val randomBytes = ByteArray(16)
289
wasiRawRandomGet(randomBytes) // Cryptographically secure
290
291
// Set version and variant bits according to RFC 4122
292
randomBytes[6] = (randomBytes[6].toInt() and 0x0F or 0x40).toByte() // Version 4
293
randomBytes[8] = (randomBytes[8].toInt() and 0x3F or 0x80).toByte() // Variant 10
294
```
295
296
### Uniqueness Guarantees
297
298
Version 4 UUIDs provide strong uniqueness guarantees:
299
300
- **Collision Probability**: Approximately 1 in 2^122 for random UUIDs
301
- **Practical Uniqueness**: Suitable for distributed systems without coordination
302
- **Timeline Independence**: No dependency on system clocks or MAC addresses
303
304
### String Representation
305
306
UUIDs are formatted according to the standard representation:
307
308
- **36 characters**: 32 hexadecimal digits plus 4 hyphens
309
- **Lowercase**: Hexadecimal digits are lowercase (a-f)
310
- **Fixed positions**: Hyphens at positions 8, 13, 18, and 23
311
312
## Performance Considerations
313
314
### Generation Performance
315
316
```kotlin
317
// Efficient: Batch generation when possible
318
val uuids = mutableListOf<Uuid>()
319
repeat(1000) {
320
uuids.add(Uuid.random()) // Each call may use cached random data
321
}
322
323
// Consider pre-generating UUIDs for high-frequency use
324
class UuidPool {
325
private val pool = mutableListOf<Uuid>()
326
327
init {
328
refill()
329
}
330
331
fun get(): Uuid {
332
if (pool.isEmpty()) refill()
333
return pool.removeAt(pool.size - 1)
334
}
335
336
private fun refill() {
337
repeat(100) { pool.add(Uuid.random()) }
338
}
339
}
340
```
341
342
### Memory Efficiency
343
344
- **Fixed Size**: Each UUID instance uses 16 bytes for storage
345
- **Immutable**: UUID instances are immutable, reducing memory management overhead
346
- **String Caching**: String representation may be cached internally
347
348
### Comparison Performance
349
350
```kotlin
351
// UUID equality is fast (compares two longs)
352
val uuid1 = Uuid.random()
353
val uuid2 = Uuid.random()
354
val equal = uuid1 == uuid2 // Fast bit comparison
355
356
// Hash code computation is efficient
357
val hashCode = uuid1.hashCode() // XOR of high and low bits
358
```
359
360
## Best Practices
361
362
### When to Use UUIDs
363
364
UUIDs are ideal for:
365
366
- **Distributed Systems**: No central authority needed for ID generation
367
- **Database Primary Keys**: Especially in sharded or replicated databases
368
- **API Identifiers**: Public-facing resource identifiers
369
- **Security Tokens**: Session IDs, API keys, temporary tokens
370
- **Event Tracking**: Correlation IDs for logging and tracing
371
372
### Security Considerations
373
374
```kotlin
375
// DO: Use random UUIDs for security-sensitive applications
376
val sessionId = Uuid.random() // Cryptographically secure
377
378
// DON'T: Use predictable patterns for security tokens
379
// val badId = "user_${System.currentTimeMillis()}" // Predictable
380
381
// DO: Treat UUIDs as opaque identifiers
382
val resourceId = Uuid.random()
383
// Use only for identification, not for encoding information
384
385
// DON'T: Store sensitive information in UUID format
386
// Uuid.fromString("secret_${password}_data") // Not actually supported
387
```
388
389
### Performance Optimization
390
391
```kotlin
392
// For high-throughput applications, consider pooling
393
class OptimizedIdGenerator {
394
companion object {
395
private val pool = ThreadLocal.withInitial { UuidPool() }
396
397
fun nextId(): Uuid = pool.get().get()
398
}
399
}
400
401
// Use string representation efficiently
402
val uuid = Uuid.random()
403
val idString = uuid.toString() // Cache if used frequently
404
```
405
406
### Database Integration
407
408
```kotlin
409
// Store UUIDs as strings in databases for broad compatibility
410
fun saveUser(user: User) {
411
val query = "INSERT INTO users (id, name, email) VALUES (?, ?, ?)"
412
// Convert UUID to string for database storage
413
executeQuery(query, user.id.toString(), user.name, user.email)
414
}
415
416
// Parse UUIDs from database strings
417
fun loadUser(idString: String): User? {
418
val uuid = Uuid.fromString(idString) // If supported by implementation
419
// Or parse manually if needed
420
return findUserById(uuid)
421
}
422
```