Как создать GUID в C? - PullRequest
       43

Как создать GUID в C?

4 голосов
/ 13 сентября 2011

Я хочу сгенерировать направляющие для вставки в базу данных SQLite (т. Е. Нет поддержки самой базы данных). Тем не менее, я хотел бы контролировать некоторые свойства:

  1. Упорядоченность для создания возрастающих значений направляющих.
  2. Компьютерная независимость. БД общедоступна и может / может не хотеть, чтобы проводники позволяли кому-либо отслеживать данные обратно на конкретную машину.
  3. «Достаточно» случайности. Направляющие являются ключами в БД, которая будет объединена со многими другими БД и может стать довольно большой, что означает, что подделка гида, как это делают многие алгоритмы, не годится.
  4. Я могу справиться с использованием системных API-интерфейсов, но, пожалуйста, свяжите функции Windows и Linux, и что-то вроде SQLite предпочтительнее, где я могу просто использовать код, написанный кем-то другим.
  5. Я также предпочел бы код, который можно использовать в коммерческих приложениях.

Ответы [ 3 ]

5 голосов
/ 24 февраля 2014

Одно из мест, где можно найти ответ для создания GUID, который содержит множество элементов, которые ищет автор, - это PHP .. http://us3.php.net/uniqid .. В своих примерах они обсуждают, как добавлять имена серверов,Имена базы данных и другие элементы GUID.

Однако, чтобы удовлетворить потребность в функции GUID на основе C, здесь приведен код, основанный на функции JavaScript. Создать GUID / UUID в JavaScript? .. этот пример использует RegEx для создания GUID.

Ниже приведен код, который создаст GUID на основе примера JavaSCript.Я уверен, что есть более элегантные решения.Это что-то сложенное вместе, чтобы дать чистый пример для подражания.

srand (clock());
char GUID[40];
int t = 0;
char *szTemp = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
char *szHex = "0123456789ABCDEF-";
int nLen = strlen (szTemp);

for (t=0; t<nLen+1; t++)
{
    int r = rand () % 16;
    char c = ' ';   

    switch (szTemp[t])
    {
        case 'x' : { c = szHex [r]; } break;
        case 'y' : { c = szHex [r & 0x03 | 0x08]; } break;
        case '-' : { c = '-'; } break;
        case '4' : { c = '4'; } break;
    }

    GUID[t] = ( t < nLen ) ? c : 0x00;
}

printf ("%s\r\n", GUID);

Примечание: строки заканчиваются символом 0x00.

4 голосов
/ 13 сентября 2011

Во-первых, GUID не случайны, они очень хорошо определены математически.

Что касается вашей проблемы, поместите создание GUID в саму базу данных как хранимую процедуру, чтобы система не зависела от платформы.,Затем сделайте GUID автоматически увеличивающимся целым числом с префиксом идентификатора базы данных.Префикс позволяет легко объединять базы данных.Идентификатор базы данных должен быть уникальным для каждой базы данных.Если вы контролируете каждую базу данных, то просто убедиться, что они уникальны.В противном случае вам может понадобиться система поиска, которая отображает IP-адрес базы данных (или какой-то другой уникальный идентификатор) на уникальный идентификатор базы данных.

Если у вас нет хранимых процедур, создайте таблицу с «NextIndex» и «DatabaseID "и обновите их при добавлении новой записи:

read NextIndex and DatabaseID
increment NextIndex
ID = NextIndex + DatabaseID
add new record, setting "GUID" to the ID value
3 голосов
/ 13 сентября 2011

Вы можете использовать или посмотреть код Boost.Uuid:

http://www.boost.org/doc/libs/1_47_0/libs/uuid/index.html

Это библиотека C ++, но, тем не менее, вы можете найти внутри, как автор кода получилUuid на нескольких системах.В последний раз, когда я проверял (январь 2010), я нашел по крайней мере следующие реализации для Windows и Linux / Solaris (эта информация может быть устаревшей):

UUID / GUID в Linux / Solaris

Открытьфайл в /dev/urandom и чтение достаточного количества байтов (16) для создания GUID / UUID.

UUID / GUID в Windows

Используйте следующие функции WinAPI

  • CryptAcquireContext для получения случайного контекста
  • CryptReleaseContext для освобождения полученного случайного контекста
  • CryptGenRandom для генерации достаточного количества байтовдля создания GUID / UUID

Другие реализации

Страница Wikipedia на GUID / UUID содержит список альтернативных реализаций, которые вы можете использовать / изучать:

https://en.wikipedia.org/wiki/UUID#Implementations

О ваших условиях

Существует тип GUID / UUID, который всегда является случайным ( версия 4 ), что означает совместимость с другими GUID / UUIDсемантика, вы должны уважать это.

Теперь вы хотитеGUID / UUID должен быть заказан вовремя.Единственный способ сделать это без ослабления случайности GUID / UUID - это поставить префикс 16-байтового GUID / UUID целым числом без знака (что сделает ваши данные идентификатора 20 байтами или более, в зависимости от вашего целого числа).Просто сгенерируйте GUID / UUID и увеличьте целое число.

...