| 
          // zig 0.14.0-dev.1511+54b668f8a (2024-09-12) | 
        
        
           | 
          // zig build-exe uuidv7.zig  -O ReleaseSmall -femit-bin=uuidv7 | 
        
        
           | 
          // Copyright 2024 (c) AJ ONeal | 
        
        
           | 
          // Licensed under the MPL-2.0 | 
        
        
           | 
          
 | 
        
        
           | 
          const std = @import("std"); | 
        
        
           | 
          const builtin = @import("builtin"); | 
        
        
           | 
          
 | 
        
        
           | 
          pub fn main() !void { | 
        
        
           | 
              const stdout = std.io.getStdOut().writer(); | 
        
        
           | 
          
 | 
        
        
           | 
              const getrandom = if (builtin.os.tag == .windows) std.os.windows.RtlGenRandom else std.posix.getrandom; | 
        
        
           | 
          
 | 
        
        
           | 
              const uuid7 = try generateUUIDv7(getrandom); | 
        
        
           | 
              const uuid7str = try uuidToString(uuid7); | 
        
        
           | 
              try stdout.print("{s}\n", .{uuid7str}); | 
        
        
           | 
          } | 
        
        
           | 
          
 | 
        
        
           | 
          pub const UUID = struct { | 
        
        
           | 
              time_high: u32, | 
        
        
           | 
              time_low: u16, | 
        
        
           | 
              version_random1: u16, | 
        
        
           | 
              variant_random2: u16, | 
        
        
           | 
              random3: u16, | 
        
        
           | 
              random4: u32, | 
        
        
           | 
          }; | 
        
        
           | 
          
 | 
        
        
           | 
          fn generateUUIDv7(getrandom: anytype) !UUID { | 
        
        
           | 
              // Get the current Unix timestamp in milliseconds | 
        
        
           | 
              const inow = std.time.milliTimestamp(); | 
        
        
           | 
              const now: u64 = @intCast(inow); // we use 48 bits | 
        
        
           | 
          
 | 
        
        
           | 
              const time_low: u16 = @truncate(now); | 
        
        
           | 
              const time_high: u32 = @truncate(now >> 16); | 
        
        
           | 
          
 | 
        
        
           | 
              const version = (0b111 << 12); // 0b111 is the 7 in UUIDv7 | 
        
        
           | 
              const version_mask = 0x0FFF; | 
        
        
           | 
          
 | 
        
        
           | 
              const variant = (0b10 << 14); // 0b10 is the endianness-indicating variant | 
        
        
           | 
              const variant_mask = 0b0011111111111111; | 
        
        
           | 
          
 | 
        
        
           | 
              var random_bytes: [10]u8 = undefined; | 
        
        
           | 
              try getrandom(&random_bytes); | 
        
        
           | 
          
 | 
        
        
           | 
              const version_random1: u16 = (((@as(u16, random_bytes[0]) << 8) | @as(u16, random_bytes[1])) & | 
        
        
           | 
                  version_mask) | version; | 
        
        
           | 
              const variant_random2: u16 = ((((@as(u16, random_bytes[2]) << 8) | @as(u16, random_bytes[3])) & | 
        
        
           | 
                  variant_mask)) | variant; | 
        
        
           | 
              const random3: u16 = (@as(u16, random_bytes[4]) << 8) | @as(u16, random_bytes[5]); | 
        
        
           | 
              const random4: u32 = (@as(u32, random_bytes[6]) << 24) | | 
        
        
           | 
                  (@as(u32, random_bytes[7]) << 16) | | 
        
        
           | 
                  (@as(u32, random_bytes[8]) << 8) | | 
        
        
           | 
                  @as(u32, random_bytes[9]); | 
        
        
           | 
          
 | 
        
        
           | 
              return UUID{ | 
        
        
           | 
                  .time_high = time_high, | 
        
        
           | 
                  .time_low = time_low, | 
        
        
           | 
                  .version_random1 = version_random1, | 
        
        
           | 
                  .variant_random2 = variant_random2, | 
        
        
           | 
                  .random3 = random3, | 
        
        
           | 
                  .random4 = random4, | 
        
        
           | 
              }; | 
        
        
           | 
          } | 
        
        
           | 
          
 | 
        
        
           | 
          fn uuidToString(uuid: UUID) ![]const u8 { | 
        
        
           | 
              var buffer: [36]u8 = undefined; | 
        
        
           | 
              // time_h32-t_16-verh-varh-rand03rand04 | 
        
        
           | 
              // 019212d3-87f4-7d25-902e-b8d39fe07f08 | 
        
        
           | 
              return std.fmt.bufPrint(&buffer, "{x:08}-{x}-{x}-{x:04}-{x:04}{x:08}", .{ uuid.time_high, uuid.time_low, uuid.version_random1, uuid.variant_random2, uuid.random3, uuid.random4 }); | 
        
        
           | 
          } |