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 "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
|
||||
guid_new(void)
|
||||
{
|
||||
struct guid guid = {0};
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
char g[GUID_SIZE];
|
||||
@ -42,6 +57,8 @@ struct guid
|
||||
/**
|
||||
* Get an initialised GUID
|
||||
*
|
||||
* The GUID is compatible with RFC4122 section 4.4.
|
||||
*
|
||||
* @return new GUID
|
||||
*/
|
||||
struct guid guid_new(void);
|
||||
|
@ -57,6 +57,42 @@ START_TEST(test_guid_to_str_ignore)
|
||||
}
|
||||
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 *
|
||||
@ -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_nscodec);
|
||||
tcase_add_test(tc_guid, test_guid_to_str_ignore);
|
||||
tcase_add_test(tc_guid, test_guid_to_str_random);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user