Skip to content

Instantly share code, notes, and snippets.

@CandyMi
Last active October 20, 2022 15:08
Show Gist options
  • Save CandyMi/facfaaa6826038086b1ccb5f39c32cd9 to your computer and use it in GitHub Desktop.
Save CandyMi/facfaaa6826038086b1ccb5f39c32cd9 to your computer and use it in GitHub Desktop.
UUID 1-5 实现
/*
** LICENSE: BSD
** Author: CandyMi[https://github.com/candymi]
*/
#include "lcrypto.h"
#define GUID_LENGTH 35
int lguid(lua_State *L) {
const uint8_t* hash = (const uint8_t*)luaL_checkstring(L, 1);
int hi = luaL_checkinteger(L, 2); int lo = luaL_checkinteger(L, 3);
uint8_t rand_bytes[2]; RAND_bytes(rand_bytes, 2);
char fmt[GUID_LENGTH + 1]; fmt[GUID_LENGTH] = '\x00';
snprintf(fmt, GUID_LENGTH + 1, "%02x%02x%02x%02x%02x%02x%02x%02x-%08x-%04x-%02x%02x",
hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7],
(uint32_t)hi, (uint16_t)lo, rand_bytes[0], rand_bytes[1]
);
lua_pushlstring(L, fmt, GUID_LENGTH);
return 1;
}
#define UUID_LENGTH 36
/* 固定值 */
static inline uint64_t uuid_gettime() {
struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts);
return ((ts.tv_sec * 10000000) + (ts.tv_nsec / 100)) + ((0x01B21DD2UL << 32) | 0x13814000);
}
int luuid_v1(lua_State *L) {
uint8_t uuid[16];
uint64_t ts = uuid_gettime();
uint32_t time_low = ts & 0xFFFFFFFF;
uint16_t time_mid = (ts >> 32) & 0x0000FFFF;
uint16_t time_hiv = ((ts >> 48) & 0x00000FFF) | 0x1000;
/* Time Low */
uuid[0] = (unsigned char)((time_low >> 24) & 0xFF);
uuid[1] = (unsigned char)((time_low >> 16) & 0xFF);
uuid[2] = (unsigned char)((time_low >> 8) & 0xFF);
uuid[3] = (unsigned char)((time_low >> 0) & 0xFF);
/* Time Mid */
uuid[4] = (unsigned char)((time_mid >> 8) & 0xFF);
uuid[5] = (unsigned char)((time_mid >> 0) & 0xFF);
/* Time High and Version */
uuid[6] = (unsigned char)((time_hiv >> 8) & 0xFF);
uuid[7] = (unsigned char)((time_hiv >> 0) & 0xFF);
RAND_bytes(uuid + 10, 6); uuid[8] = 127; uuid[9] = 1;
uuid[8] = (unsigned char)(0x80 | (uuid[8] & 0x3F));
char fmt[UUID_LENGTH + 1]; fmt[UUID_LENGTH] = '\x00';
snprintf(fmt, UUID_LENGTH + 1, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]
);
lua_pushlstring(L, fmt, UUID_LENGTH);
return 1;
}
int luuid_v2(lua_State *L) {
uint8_t uuid[16];
uint64_t ts = uuid_gettime();
uint32_t time_low = ts & 0xFFFFFFFF;
uint16_t time_mid = (ts >> 32) & 0x0000FFFF;
uint16_t time_hiv = ((ts >> 48) & 0x00000FFF) | 0x2000;
/* Time Low */
uuid[0] = (unsigned char)((time_low >> 24) & 0xFF);
uuid[1] = (unsigned char)((time_low >> 16) & 0xFF);
uuid[2] = (unsigned char)((time_low >> 8) & 0xFF);
uuid[3] = (unsigned char)((time_low >> 0) & 0xFF);
/* Time Mid */
uuid[4] = (unsigned char)((time_mid >> 8) & 0xFF);
uuid[5] = (unsigned char)((time_mid >> 0) & 0xFF);
/* Time High and Version */
uuid[6] = (unsigned char)((time_hiv >> 8) & 0xFF);
uuid[7] = (unsigned char)((time_hiv >> 0) & 0xFF);
RAND_bytes(uuid + 8, 8); uuid[8] = (unsigned char)(0x80 | (uuid[8] & 0x3F));
char fmt[UUID_LENGTH + 1]; fmt[UUID_LENGTH] = '\x00';
snprintf(fmt, UUID_LENGTH + 1, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]
);
lua_pushlstring(L, fmt, UUID_LENGTH);
return 1;
}
int luuid_v3(lua_State *L) {
size_t nsize;
const char* ns = luaL_checklstring(L, 1, &nsize);
unsigned int mdlen = EVP_MAX_BLOCK_LENGTH;
unsigned char md[EVP_MAX_BLOCK_LENGTH];
EVP_Digest(ns, nsize, md, &mdlen, EVP_md5(), NULL);
uint8_t uuid[16];
memcpy(uuid, md, 16);
uuid[6] = (unsigned char)(0x30 | (uuid[6] & 0x0F));
uuid[8] = (unsigned char)(0x80 | (uuid[8] & 0x3F));
char fmt[UUID_LENGTH + 1]; fmt[UUID_LENGTH] = '\x00';
snprintf(fmt, UUID_LENGTH + 1, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]
);
lua_pushlstring(L, fmt, UUID_LENGTH);
return 1;
}
int luuid_v4(lua_State *L) {
uint8_t uuid[16]; RAND_bytes(uuid, sizeof(uuid));
uuid[6] = (unsigned char)(0x40 | (uuid[6] & 0x0F));
uuid[8] = (unsigned char)(0x80 | (uuid[8] & 0x3F));
char fmt[UUID_LENGTH + 1]; fmt[UUID_LENGTH] = '\x00';
snprintf(fmt, UUID_LENGTH + 1, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]
);
lua_pushlstring(L, fmt, UUID_LENGTH);
return 1;
}
int luuid_v5(lua_State *L) {
size_t nsize;
const char* ns = luaL_checklstring(L, 1, &nsize);
unsigned int mdlen = EVP_MAX_BLOCK_LENGTH;
unsigned char md[EVP_MAX_BLOCK_LENGTH];
EVP_Digest(ns, nsize, md, &mdlen, EVP_sha1(), NULL);
uint8_t uuid[16];
memcpy(uuid, md, 16);
uuid[6] = (unsigned char)(0x50 | (uuid[6] & 0x0F));
uuid[8] = (unsigned char)(0x80 | (uuid[8] & 0x3F));
char fmt[UUID_LENGTH + 1]; fmt[UUID_LENGTH] = '\x00';
snprintf(fmt, UUID_LENGTH + 1, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]
);
lua_pushlstring(L, fmt, UUID_LENGTH);
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment