#include // printf za izpis #include // srand, rand za RNG #include // time za seedanje PRNG #include // fiksne velikosti int podatkov #include // CRC32 // Kristjan Komloši, 2024 // UUID generator, 1. domača naloga POKS // Program se prevede z // gcc uuid-gen.c -lz union serial_union // za razbijanje serijske na posamezne bajte { uint32_t serial; // serijska uint8_t bytes[4]; // za CRC32, ki pričakuje posamezne bajte }; // struktura, ki skupaj poveze serijsko, nakljucni uuid in CRC32 struct uuid_uint128 { uint8_t uuid_byte[16]; union serial_union serial; uint32_t crc; }; void get_uuid(struct uuid_uint128 *uuid) { // funkcija v pokazano UUID strukturo vpise v4 uuid (nakljucni) s serijsko stevilko in CRCjem // xx xx xx xx - xx xx - Mx xx - Nx xx - xx xx xx xx xx xx // M = verzija (0x4) // N = varianta (0b10xx) // byte maske za te vrednosti static uint32_t serial = 1; const uint8_t version_mask_or = 0x40; const uint8_t version_mask_and = 0x0F; const uint8_t variant_mask_or = 0x80; const uint8_t variant_mask_and = 0x3F; uuid->serial.serial = serial++; // nastavimo naslednjo serijsko for (int c = 0; c < sizeof(uuid->uuid_byte); c++) { // vzamemo stevilo iz RNG, ga prestavimo v interval [0,255], vpisemo uuid->uuid_byte[c] = (uint8_t)((double)rand() / RAND_MAX * 255); } // maskiranje bitov za verzijo in varianto uuid->uuid_byte[6] &= version_mask_and; uuid->uuid_byte[6] |= version_mask_or; uuid->uuid_byte[8] &= variant_mask_and; uuid->uuid_byte[8] |= variant_mask_or; // Zlib ima implementacijo CRC-32 // Glej https://refspecs.linuxbase.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/zlib-crc32-1.html uuid->crc = crc32(0, Z_NULL, 0); // inicializacija uuid->crc = crc32(uuid->crc, uuid->serial.bytes, sizeof(uuid->serial.bytes)); // dodamo serijsko uuid->crc = crc32(uuid->crc, uuid->uuid_byte, sizeof(uuid->uuid_byte)); // dodamo vse byte UUIDja }; void print_uuid(struct uuid_uint128 uuid) { // funkcija je samo alias za ta dolgovezni printf printf("%08d-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x %08x\n", uuid.serial.serial, uuid.uuid_byte[0], uuid.uuid_byte[1], uuid.uuid_byte[2], uuid.uuid_byte[3], uuid.uuid_byte[4], uuid.uuid_byte[5], uuid.uuid_byte[6], uuid.uuid_byte[7], uuid.uuid_byte[8], uuid.uuid_byte[9], uuid.uuid_byte[10], uuid.uuid_byte[11], uuid.uuid_byte[12], uuid.uuid_byte[13], uuid.uuid_byte[14], uuid.uuid_byte[15], uuid.crc ); } int main(void) { srand(time(NULL)); // seed RNG struct uuid_uint128 uuid; for (int i = 0; i < 100; i++) { get_uuid(&uuid); print_uuid(uuid); } }