92 lines
2.6 KiB
C
92 lines
2.6 KiB
C
#include <stdio.h> // printf za izpis
|
|
#include <stdlib.h> // srand, rand za RNG
|
|
#include <time.h> // time za seedanje PRNG
|
|
#include <stdint.h> // fiksne velikosti int podatkov
|
|
#include <zlib.h> // CRC32
|
|
// Kristjan Komloši, 2024
|
|
// UUID generator, 1. domača naloga POKS
|
|
// Program se prevede z
|
|
// gcc uuid-gen.c -lz
|
|
|
|
|
|
// struktura, ki skupaj poveze serijsko, nakljucni uuid in CRC32
|
|
struct uuid_uint128
|
|
{
|
|
uint8_t uuid_byte[16];
|
|
char 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 char 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++; // 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, 1); // 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,
|
|
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++) // zaradi racunanja serijske in CRC je maksimum 255 iteracij
|
|
{
|
|
get_uuid(&uuid);
|
|
print_uuid(uuid);
|
|
}
|
|
|
|
}
|