mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 15:36:17 +01:00
guuid: Add UUID helper functions to GLib
Many UUID users will just need a random string, which can be generated simply by calling the function g_uuid_string_random(). Based on original patch by Marc-André Lureau <marcandre.lureau@gmail.com> https://bugzilla.gnome.org/show_bug.cgi?id=639078
This commit is contained in:
parent
edc68f2659
commit
215c9b7951
@ -94,6 +94,7 @@
|
|||||||
<xi:include href="xml/testing.xml" />
|
<xi:include href="xml/testing.xml" />
|
||||||
<xi:include href="xml/gunix.xml" />
|
<xi:include href="xml/gunix.xml" />
|
||||||
<xi:include href="xml/windows.xml" />
|
<xi:include href="xml/windows.xml" />
|
||||||
|
<xi:include href="xml/uuid.xml" />
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="glib-data-types">
|
<chapter id="glib-data-types">
|
||||||
|
@ -3403,3 +3403,10 @@ g_hostname_is_ascii_encoded
|
|||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
g_hostname_is_ip_address
|
g_hostname_is_ip_address
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>uuid</FILE>
|
||||||
|
<TITLE>GUuid</TITLE>
|
||||||
|
g_uuid_string_is_valid
|
||||||
|
g_uuid_string_random
|
||||||
|
</SECTION>
|
||||||
|
@ -188,6 +188,7 @@ libglib_2_0_la_SOURCES = \
|
|||||||
gunicodeprivate.h \
|
gunicodeprivate.h \
|
||||||
gurifuncs.c \
|
gurifuncs.c \
|
||||||
gutils.c \
|
gutils.c \
|
||||||
|
guuid.c \
|
||||||
gvariant.h \
|
gvariant.h \
|
||||||
gvariant.c \
|
gvariant.c \
|
||||||
gvariant-core.h \
|
gvariant-core.h \
|
||||||
@ -309,6 +310,7 @@ glibsubinclude_HEADERS = \
|
|||||||
gunicode.h \
|
gunicode.h \
|
||||||
gurifuncs.h \
|
gurifuncs.h \
|
||||||
gutils.h \
|
gutils.h \
|
||||||
|
guuid.h \
|
||||||
gvarianttype.h \
|
gvarianttype.h \
|
||||||
gvariant.h \
|
gvariant.h \
|
||||||
gversion.h \
|
gversion.h \
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
#include <glib/gunicode.h>
|
#include <glib/gunicode.h>
|
||||||
#include <glib/gurifuncs.h>
|
#include <glib/gurifuncs.h>
|
||||||
#include <glib/gutils.h>
|
#include <glib/gutils.h>
|
||||||
|
#include <glib/guuid.h>
|
||||||
#include <glib/gvarianttype.h>
|
#include <glib/gvarianttype.h>
|
||||||
#include <glib/gvariant.h>
|
#include <glib/gvariant.h>
|
||||||
#include <glib/gversion.h>
|
#include <glib/gversion.h>
|
||||||
|
231
glib/guuid.c
Normal file
231
glib/guuid.c
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
/* guuid.c - UUID functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015, 2017 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
* licence, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Authors: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gi18n.h"
|
||||||
|
#include "gstrfuncs.h"
|
||||||
|
#include "grand.h"
|
||||||
|
#include "gmessages.h"
|
||||||
|
#include "gchecksum.h"
|
||||||
|
|
||||||
|
#include "guuid.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
guint8 bytes[16];
|
||||||
|
} GUuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:uuid
|
||||||
|
* @title: GUuid
|
||||||
|
* @short_description: a universally unique identifier
|
||||||
|
*
|
||||||
|
* A UUID, or Universally unique identifier, is intended to uniquely
|
||||||
|
* identify information in a distributed environment. For the
|
||||||
|
* definition of UUID, see [RFC 4122](https://tools.ietf.org/html/rfc4122.html).
|
||||||
|
*
|
||||||
|
* The creation of UUIDs does not require a centralized authority.
|
||||||
|
*
|
||||||
|
* UUIDs are of relatively small size (128 bits, or 16 bytes). The
|
||||||
|
* common string representation (ex:
|
||||||
|
* 1d6c0810-2bd6-45f3-9890-0268422a6f14) needs 37 bytes.
|
||||||
|
*
|
||||||
|
* The UUID specification defines 5 versions, and calling
|
||||||
|
* g_uuid_string_random() will generate a unique (or rather random)
|
||||||
|
* UUID of the most common version, version 4.
|
||||||
|
*
|
||||||
|
* Since: 2.52
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g_uuid_to_string:
|
||||||
|
* @uuid: a #GUuid
|
||||||
|
*
|
||||||
|
* Creates a string representation of @uuid, of the form
|
||||||
|
* 06e023d5-86d8-420e-8103-383e4566087a (no braces nor urn:uuid:
|
||||||
|
* prefix).
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A string that should be freed with g_free().
|
||||||
|
* Since: STATIC
|
||||||
|
*/
|
||||||
|
static gchar *
|
||||||
|
g_uuid_to_string (const GUuid *uuid)
|
||||||
|
{
|
||||||
|
const guint8 *bytes;
|
||||||
|
|
||||||
|
g_return_val_if_fail (uuid != NULL, NULL);
|
||||||
|
|
||||||
|
bytes = uuid->bytes;
|
||||||
|
|
||||||
|
return g_strdup_printf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x"
|
||||||
|
"-%02x%02x%02x%02x%02x%02x",
|
||||||
|
bytes[0], bytes[1], bytes[2], bytes[3],
|
||||||
|
bytes[4], bytes[5], bytes[6], bytes[7],
|
||||||
|
bytes[8], bytes[9], bytes[10], bytes[11],
|
||||||
|
bytes[12], bytes[13], bytes[14], bytes[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
uuid_parse_string (const gchar *str,
|
||||||
|
GUuid *uuid)
|
||||||
|
{
|
||||||
|
GUuid tmp;
|
||||||
|
guint8 *bytes = tmp.bytes;
|
||||||
|
gint i, j, hi, lo;
|
||||||
|
guint expected_len = 36;
|
||||||
|
|
||||||
|
if (g_str_has_prefix (str, "urn:uuid:"))
|
||||||
|
str += 9;
|
||||||
|
else if (g_str_has_prefix (str, "{urn:uuid:"))
|
||||||
|
expected_len += 11;
|
||||||
|
else if (str[0] == '{')
|
||||||
|
expected_len += 2;
|
||||||
|
|
||||||
|
if (strlen (str) != expected_len)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (str[0] == '{')
|
||||||
|
{
|
||||||
|
if (str[expected_len - 1] != '}')
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_str_has_prefix (str, "urn:uuid:"))
|
||||||
|
str += 9;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < 16;)
|
||||||
|
{
|
||||||
|
if (j == 8 || j == 13 || j == 18 || j == 23)
|
||||||
|
{
|
||||||
|
if (str[j++] != '-')
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hi = g_ascii_xdigit_value (str[j++]);
|
||||||
|
lo = g_ascii_xdigit_value (str[j++]);
|
||||||
|
|
||||||
|
if (hi == -1 || lo == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
bytes[i++] = hi << 8 | lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uuid != NULL)
|
||||||
|
*uuid = tmp;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_uuid_string_is_valid:
|
||||||
|
* @str: a string representing a UUID
|
||||||
|
*
|
||||||
|
* Parses the string @str and verify if it is a UUID.
|
||||||
|
*
|
||||||
|
* The function accepts the following syntaxes:
|
||||||
|
*
|
||||||
|
* - simple forms (e.g. `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`)
|
||||||
|
* - simple forms with curly braces (e.g.
|
||||||
|
* `{urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6}`)
|
||||||
|
* - URN (e.g. `urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6`)
|
||||||
|
*
|
||||||
|
* Note that hyphens are required within the UUID string itself,
|
||||||
|
* as per the aforementioned RFC.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if @str is a valid UUID, %FALSE otherwise.
|
||||||
|
* Since: 2.52
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
g_uuid_string_is_valid (const gchar *str)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (str != NULL, FALSE);
|
||||||
|
|
||||||
|
return uuid_parse_string (str, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
uuid_set_version (GUuid *uuid, guint version)
|
||||||
|
{
|
||||||
|
guint8 *bytes = uuid->bytes;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the four most significant bits (bits 12 through 15) of the
|
||||||
|
* time_hi_and_version field to the 4-bit version number from
|
||||||
|
* Section 4.1.3.
|
||||||
|
*/
|
||||||
|
bytes[6] &= 0x0f;
|
||||||
|
bytes[6] |= version << 4;
|
||||||
|
/*
|
||||||
|
* Set the two most significant bits (bits 6 and 7) of the
|
||||||
|
* clock_seq_hi_and_reserved to zero and one, respectively.
|
||||||
|
*/
|
||||||
|
bytes[8] &= 0x3f;
|
||||||
|
bytes[8] |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g_uuid_generate_v4:
|
||||||
|
* @uuid: a #GUuid
|
||||||
|
*
|
||||||
|
* Generates a random UUID (RFC 4122 version 4).
|
||||||
|
* Since: STATIC
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
g_uuid_generate_v4 (GUuid *uuid)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
guint8 *bytes;
|
||||||
|
guint32 *ints;
|
||||||
|
|
||||||
|
g_return_if_fail (uuid != NULL);
|
||||||
|
|
||||||
|
bytes = uuid->bytes;
|
||||||
|
ints = (guint32 *) bytes;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
ints[i] = g_random_int ();
|
||||||
|
|
||||||
|
uuid_set_version (uuid, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_uuid_string_random:
|
||||||
|
*
|
||||||
|
* Generates a random UUID (RFC 4122 version 4) as a string.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A string that should be freed with g_free().
|
||||||
|
* Since: 2.52
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
g_uuid_string_random (void)
|
||||||
|
{
|
||||||
|
GUuid uuid;
|
||||||
|
|
||||||
|
g_uuid_generate_v4 (&uuid);
|
||||||
|
|
||||||
|
return g_uuid_to_string (&uuid);
|
||||||
|
}
|
||||||
|
|
42
glib/guuid.h
Normal file
42
glib/guuid.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* guuid.h - UUID functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015, 2017 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
* licence, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Authors: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __G_UUID_H__
|
||||||
|
#define __G_UUID_H__
|
||||||
|
|
||||||
|
#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
|
||||||
|
#error "Only <glib.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib/gtypes.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_52
|
||||||
|
gboolean g_uuid_string_is_valid (const gchar *str);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_52
|
||||||
|
gchar * g_uuid_string_random (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __G_UUID_H__ */
|
1
glib/tests/.gitignore
vendored
1
glib/tests/.gitignore
vendored
@ -22,6 +22,7 @@ environment
|
|||||||
error
|
error
|
||||||
fileutils
|
fileutils
|
||||||
gdatetime
|
gdatetime
|
||||||
|
guuid
|
||||||
gvariant
|
gvariant
|
||||||
gwakeup
|
gwakeup
|
||||||
gwakeup-fallback
|
gwakeup-fallback
|
||||||
|
@ -59,6 +59,7 @@ test_programs = \
|
|||||||
error \
|
error \
|
||||||
fileutils \
|
fileutils \
|
||||||
gdatetime \
|
gdatetime \
|
||||||
|
guuid \
|
||||||
gvariant \
|
gvariant \
|
||||||
hash \
|
hash \
|
||||||
hmac \
|
hmac \
|
||||||
|
71
glib/tests/guuid.c
Normal file
71
glib/tests/guuid.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/* guuid.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015, 2017 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#undef G_DISABLE_ASSERT
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_guuid_string (void)
|
||||||
|
{
|
||||||
|
g_assert_false (g_uuid_string_is_valid ("00010203-0405-0607-0809"));
|
||||||
|
g_assert_false (g_uuid_string_is_valid ("zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz"));
|
||||||
|
g_assert_false (g_uuid_string_is_valid ("000102030405060708090a0b0c0d0e0f"));
|
||||||
|
|
||||||
|
g_assert_true (g_uuid_string_is_valid ("00010203-0405-0607-0809-0a0b0c0d0e0f"));
|
||||||
|
g_assert_true (g_uuid_string_is_valid ("7d444840-9dc0-11d1-b245-5ffdce74fad2"));
|
||||||
|
g_assert_true (g_uuid_string_is_valid ("e902893a-9d22-3c7e-a7b8-d6e313b71d9f"));
|
||||||
|
g_assert_true (g_uuid_string_is_valid ("6ba7b810-9dad-11d1-80b4-00c04fd430c8"));
|
||||||
|
g_assert_true (g_uuid_string_is_valid ("{urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6}"));
|
||||||
|
g_assert_true (g_uuid_string_is_valid ("urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_guuid_random (void)
|
||||||
|
{
|
||||||
|
gchar *str1, *str2;
|
||||||
|
|
||||||
|
str1 = g_uuid_string_random ();
|
||||||
|
g_assert_cmpuint (strlen (str1), ==, 36);
|
||||||
|
g_assert_true (g_uuid_string_is_valid (str1));
|
||||||
|
|
||||||
|
str2 = g_uuid_string_random ();
|
||||||
|
g_assert_cmpuint (strlen (str2), ==, 36);
|
||||||
|
g_assert_true (g_uuid_string_is_valid (str2));
|
||||||
|
g_assert_cmpstr (str1, !=, str2);
|
||||||
|
|
||||||
|
g_free (str1);
|
||||||
|
g_free (str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||||
|
|
||||||
|
/* GUuid Tests */
|
||||||
|
g_test_add_func ("/uuid/string", test_guuid_string);
|
||||||
|
g_test_add_func ("/uuid/random", test_guuid_random);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
@ -195,4 +195,5 @@ glib/gspawn.c
|
|||||||
glib/gspawn-win32.c
|
glib/gspawn-win32.c
|
||||||
glib/gutf8.c
|
glib/gutf8.c
|
||||||
glib/gutils.c
|
glib/gutils.c
|
||||||
|
glib/guuid.c
|
||||||
gobject/gbinding.c
|
gobject/gbinding.c
|
||||||
|
Loading…
Reference in New Issue
Block a user