|
Packit Service |
d3d246 |
/* guuid.c - UUID functions
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Copyright (C) 2013-2015, 2017 Red Hat, Inc.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* This library is free software; you can redistribute it and/or modify
|
|
Packit Service |
d3d246 |
* it under the terms of the GNU Lesser General Public License as
|
|
Packit Service |
d3d246 |
* published by the Free Software Foundation; either version 2.1 of the
|
|
Packit Service |
d3d246 |
* licence, or (at your option) any later version.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* This is distributed in the hope that it will be useful, but WITHOUT
|
|
Packit Service |
d3d246 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
Packit Service |
d3d246 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
Packit Service |
d3d246 |
* License for more details.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
d3d246 |
* License along with this library; if not, write to the Free Software
|
|
Packit Service |
d3d246 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
|
Packit Service |
d3d246 |
* USA.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Authors: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
Packit Service |
d3d246 |
*/
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
#include "config.h"
|
|
Packit Service |
d3d246 |
#include <string.h>
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
#include "gi18n.h"
|
|
Packit Service |
d3d246 |
#include "gstrfuncs.h"
|
|
Packit Service |
d3d246 |
#include "grand.h"
|
|
Packit Service |
d3d246 |
#include "gmessages.h"
|
|
Packit Service |
d3d246 |
#include "gchecksum.h"
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
#include "guuid.h"
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
typedef struct {
|
|
Packit Service |
d3d246 |
guint8 bytes[16];
|
|
Packit Service |
d3d246 |
} GUuid;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
/**
|
|
Packit Service |
d3d246 |
* SECTION:uuid
|
|
Packit Service |
d3d246 |
* @title: GUuid
|
|
Packit Service |
d3d246 |
* @short_description: a universally unique identifier
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* A UUID, or Universally unique identifier, is intended to uniquely
|
|
Packit Service |
d3d246 |
* identify information in a distributed environment. For the
|
|
Packit Service |
d3d246 |
* definition of UUID, see [RFC 4122](https://tools.ietf.org/html/rfc4122.html).
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* The creation of UUIDs does not require a centralized authority.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* UUIDs are of relatively small size (128 bits, or 16 bytes). The
|
|
Packit Service |
d3d246 |
* common string representation (ex:
|
|
Packit Service |
d3d246 |
* 1d6c0810-2bd6-45f3-9890-0268422a6f14) needs 37 bytes.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* The UUID specification defines 5 versions, and calling
|
|
Packit Service |
d3d246 |
* g_uuid_string_random() will generate a unique (or rather random)
|
|
Packit Service |
d3d246 |
* UUID of the most common version, version 4.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Since: 2.52
|
|
Packit Service |
d3d246 |
*/
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
/*
|
|
Packit Service |
d3d246 |
* g_uuid_to_string:
|
|
Packit Service |
d3d246 |
* @uuid: a #GUuid
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Creates a string representation of @uuid, of the form
|
|
Packit Service |
d3d246 |
* 06e023d5-86d8-420e-8103-383e4566087a (no braces nor urn:uuid:
|
|
Packit Service |
d3d246 |
* prefix).
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Returns: (transfer full): A string that should be freed with g_free().
|
|
Packit Service |
d3d246 |
* Since: STATIC
|
|
Packit Service |
d3d246 |
*/
|
|
Packit Service |
d3d246 |
static gchar *
|
|
Packit Service |
d3d246 |
g_uuid_to_string (const GUuid *uuid)
|
|
Packit Service |
d3d246 |
{
|
|
Packit Service |
d3d246 |
const guint8 *bytes;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
g_return_val_if_fail (uuid != NULL, NULL);
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
bytes = uuid->bytes;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
return g_strdup_printf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x"
|
|
Packit Service |
d3d246 |
"-%02x%02x%02x%02x%02x%02x",
|
|
Packit Service |
d3d246 |
bytes[0], bytes[1], bytes[2], bytes[3],
|
|
Packit Service |
d3d246 |
bytes[4], bytes[5], bytes[6], bytes[7],
|
|
Packit Service |
d3d246 |
bytes[8], bytes[9], bytes[10], bytes[11],
|
|
Packit Service |
d3d246 |
bytes[12], bytes[13], bytes[14], bytes[15]);
|
|
Packit Service |
d3d246 |
}
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
static gboolean
|
|
Packit Service |
d3d246 |
uuid_parse_string (const gchar *str,
|
|
Packit Service |
d3d246 |
GUuid *uuid)
|
|
Packit Service |
d3d246 |
{
|
|
Packit Service |
d3d246 |
GUuid tmp;
|
|
Packit Service |
d3d246 |
guint8 *bytes = tmp.bytes;
|
|
Packit Service |
d3d246 |
gint i, j, hi, lo;
|
|
Packit Service |
d3d246 |
guint expected_len = 36;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
if (strlen (str) != expected_len)
|
|
Packit Service |
d3d246 |
return FALSE;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
for (i = 0, j = 0; i < 16;)
|
|
Packit Service |
d3d246 |
{
|
|
Packit Service |
d3d246 |
if (j == 8 || j == 13 || j == 18 || j == 23)
|
|
Packit Service |
d3d246 |
{
|
|
Packit Service |
d3d246 |
if (str[j++] != '-')
|
|
Packit Service |
d3d246 |
return FALSE;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
continue;
|
|
Packit Service |
d3d246 |
}
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
hi = g_ascii_xdigit_value (str[j++]);
|
|
Packit Service |
d3d246 |
lo = g_ascii_xdigit_value (str[j++]);
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
if (hi == -1 || lo == -1)
|
|
Packit Service |
d3d246 |
return FALSE;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
bytes[i++] = hi << 8 | lo;
|
|
Packit Service |
d3d246 |
}
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
if (uuid != NULL)
|
|
Packit Service |
d3d246 |
*uuid = tmp;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
return TRUE;
|
|
Packit Service |
d3d246 |
}
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
/**
|
|
Packit Service |
d3d246 |
* g_uuid_string_is_valid:
|
|
Packit Service |
d3d246 |
* @str: a string representing a UUID
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Parses the string @str and verify if it is a UUID.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* The function accepts the following syntax:
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* - simple forms (e.g. `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`)
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Note that hyphens are required within the UUID string itself,
|
|
Packit Service |
d3d246 |
* as per the aforementioned RFC.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Returns: %TRUE if @str is a valid UUID, %FALSE otherwise.
|
|
Packit Service |
d3d246 |
* Since: 2.52
|
|
Packit Service |
d3d246 |
*/
|
|
Packit Service |
d3d246 |
gboolean
|
|
Packit Service |
d3d246 |
g_uuid_string_is_valid (const gchar *str)
|
|
Packit Service |
d3d246 |
{
|
|
Packit Service |
d3d246 |
g_return_val_if_fail (str != NULL, FALSE);
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
return uuid_parse_string (str, NULL);
|
|
Packit Service |
d3d246 |
}
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
static void
|
|
Packit Service |
d3d246 |
uuid_set_version (GUuid *uuid, guint version)
|
|
Packit Service |
d3d246 |
{
|
|
Packit Service |
d3d246 |
guint8 *bytes = uuid->bytes;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
/*
|
|
Packit Service |
d3d246 |
* Set the four most significant bits (bits 12 through 15) of the
|
|
Packit Service |
d3d246 |
* time_hi_and_version field to the 4-bit version number from
|
|
Packit Service |
d3d246 |
* Section 4.1.3.
|
|
Packit Service |
d3d246 |
*/
|
|
Packit Service |
d3d246 |
bytes[6] &= 0x0f;
|
|
Packit Service |
d3d246 |
bytes[6] |= version << 4;
|
|
Packit Service |
d3d246 |
/*
|
|
Packit Service |
d3d246 |
* Set the two most significant bits (bits 6 and 7) of the
|
|
Packit Service |
d3d246 |
* clock_seq_hi_and_reserved to zero and one, respectively.
|
|
Packit Service |
d3d246 |
*/
|
|
Packit Service |
d3d246 |
bytes[8] &= 0x3f;
|
|
Packit Service |
d3d246 |
bytes[8] |= 0x80;
|
|
Packit Service |
d3d246 |
}
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
/*
|
|
Packit Service |
d3d246 |
* g_uuid_generate_v4:
|
|
Packit Service |
d3d246 |
* @uuid: a #GUuid
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Generates a random UUID (RFC 4122 version 4).
|
|
Packit Service |
d3d246 |
* Since: STATIC
|
|
Packit Service |
d3d246 |
*/
|
|
Packit Service |
d3d246 |
static void
|
|
Packit Service |
d3d246 |
g_uuid_generate_v4 (GUuid *uuid)
|
|
Packit Service |
d3d246 |
{
|
|
Packit Service |
d3d246 |
int i;
|
|
Packit Service |
d3d246 |
guint8 *bytes;
|
|
Packit Service |
d3d246 |
guint32 *ints;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
g_return_if_fail (uuid != NULL);
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
bytes = uuid->bytes;
|
|
Packit Service |
d3d246 |
ints = (guint32 *) bytes;
|
|
Packit Service |
d3d246 |
for (i = 0; i < 4; i++)
|
|
Packit Service |
d3d246 |
ints[i] = g_random_int ();
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
uuid_set_version (uuid, 4);
|
|
Packit Service |
d3d246 |
}
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
/**
|
|
Packit Service |
d3d246 |
* g_uuid_string_random:
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Generates a random UUID (RFC 4122 version 4) as a string.
|
|
Packit Service |
d3d246 |
*
|
|
Packit Service |
d3d246 |
* Returns: (transfer full): A string that should be freed with g_free().
|
|
Packit Service |
d3d246 |
* Since: 2.52
|
|
Packit Service |
d3d246 |
*/
|
|
Packit Service |
d3d246 |
gchar *
|
|
Packit Service |
d3d246 |
g_uuid_string_random (void)
|
|
Packit Service |
d3d246 |
{
|
|
Packit Service |
d3d246 |
GUuid uuid;
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
g_uuid_generate_v4 (&uuid);
|
|
Packit Service |
d3d246 |
|
|
Packit Service |
d3d246 |
return g_uuid_to_string (&uuid);
|
|
Packit Service |
d3d246 |
}
|
|
Packit Service |
d3d246 |
|