guid_new() returns GUIDs compatible with RFC4122
This commit is contained in:
parent
9940f2f5ee
commit
c3bb7dc294
@ -30,11 +30,27 @@
|
|||||||
#include "os_calls.h"
|
#include "os_calls.h"
|
||||||
#include "string_calls.h"
|
#include "string_calls.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/* Field offsets in the UUID */
|
||||||
|
E_CLOCK_SEQ_HI_AND_RESERVED = 8,
|
||||||
|
E_TIME_HI_AND_VERSION_MSB = 7,
|
||||||
|
/* UUID versions from RFC4122 section 4.1.3 */
|
||||||
|
E_UUID_VERSION_RANDOM = 4
|
||||||
|
};
|
||||||
|
|
||||||
struct guid
|
struct guid
|
||||||
guid_new(void)
|
guid_new(void)
|
||||||
{
|
{
|
||||||
struct guid guid = {0};
|
struct guid guid = {0};
|
||||||
g_random(guid.g, sizeof(guid.g));
|
g_random(guid.g, sizeof(guid.g));
|
||||||
|
/* Show this UUID as conforming to RFC4122 (section 4.1.1) */
|
||||||
|
guid.g[E_CLOCK_SEQ_HI_AND_RESERVED] &= ~0x40; /* Clear bit 6 */
|
||||||
|
guid.g[E_CLOCK_SEQ_HI_AND_RESERVED] |= (char)0x80; /* Set bit 7 */
|
||||||
|
|
||||||
|
guid.g[E_TIME_HI_AND_VERSION_MSB] &= ~0xf0;
|
||||||
|
guid.g[E_TIME_HI_AND_VERSION_MSB] |= (E_UUID_VERSION_RANDOM << 4);
|
||||||
|
|
||||||
return guid;
|
return guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,8 +32,23 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use a struct for the guid so we can easily copy by assignment
|
* Use a struct for the guid so we can easily copy by assignment.
|
||||||
*/
|
* We use an array of char so that
|
||||||
|
* we can compare GUIDs with a straight memcmp()
|
||||||
|
*
|
||||||
|
* Some fields of the GUID are in little-endian-order as specified by
|
||||||
|
* [MS-DTYP]. This is at odds with RFC4122 which specifies big-endian
|
||||||
|
* order for all fields.
|
||||||
|
*
|
||||||
|
* Octets RFC4122 field
|
||||||
|
* ------ -------------
|
||||||
|
* 0-3 time_low (little-endian)
|
||||||
|
* 4-5 time_mid (little-endian)
|
||||||
|
* 6-7 time_hi_and_version (little-endian)
|
||||||
|
* 8 clock_seq_hi_and_reserved
|
||||||
|
* 9 clock_seq_low (in order)
|
||||||
|
* 10-15 node
|
||||||
|
*/
|
||||||
struct guid
|
struct guid
|
||||||
{
|
{
|
||||||
char g[GUID_SIZE];
|
char g[GUID_SIZE];
|
||||||
@ -42,6 +57,8 @@ struct guid
|
|||||||
/**
|
/**
|
||||||
* Get an initialised GUID
|
* Get an initialised GUID
|
||||||
*
|
*
|
||||||
|
* The GUID is compatible with RFC4122 section 4.4.
|
||||||
|
*
|
||||||
* @return new GUID
|
* @return new GUID
|
||||||
*/
|
*/
|
||||||
struct guid guid_new(void);
|
struct guid guid_new(void);
|
||||||
|
@ -57,6 +57,42 @@ START_TEST(test_guid_to_str_ignore)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_guid_to_str_random)
|
||||||
|
{
|
||||||
|
/* setup */
|
||||||
|
char dest[GUID_STR_SIZE];
|
||||||
|
struct guid guid;
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0 ; i < 100; ++i)
|
||||||
|
{
|
||||||
|
guid = guid_new();
|
||||||
|
/* test */
|
||||||
|
guid_to_str(&guid, dest);
|
||||||
|
|
||||||
|
/* Check all the '-' signs are in the right places */
|
||||||
|
ck_assert_int_eq(dest[8], '-');
|
||||||
|
ck_assert_int_eq(dest[13], '-');
|
||||||
|
ck_assert_int_eq(dest[18], '-');
|
||||||
|
ck_assert_int_eq(dest[23], '-');
|
||||||
|
|
||||||
|
/* Check the variant is RFC4122 */
|
||||||
|
char c = dest[18 + 1]; /* char after 3rd dash */
|
||||||
|
if (c != '8' && c != '9' && c != 'A' && c != 'B')
|
||||||
|
{
|
||||||
|
ck_abort_msg("Generated UUID is not RFC4122 compliant");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the version is 'randomly generated' */
|
||||||
|
c = dest[13 + 1]; /* char after 2nd dash */
|
||||||
|
if (c != '4')
|
||||||
|
{
|
||||||
|
ck_abort_msg("Generated UUID is not RFC4122 randomly-generated");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
Suite *
|
Suite *
|
||||||
@ -72,6 +108,7 @@ make_suite_test_guid(void)
|
|||||||
tcase_add_test(tc_guid, test_guid_to_str_remotefx);
|
tcase_add_test(tc_guid, test_guid_to_str_remotefx);
|
||||||
tcase_add_test(tc_guid, test_guid_to_str_nscodec);
|
tcase_add_test(tc_guid, test_guid_to_str_nscodec);
|
||||||
tcase_add_test(tc_guid, test_guid_to_str_ignore);
|
tcase_add_test(tc_guid, test_guid_to_str_ignore);
|
||||||
|
tcase_add_test(tc_guid, test_guid_to_str_random);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user