diff options
author | Richard Hughes <richard@hughsie.com> | 2017-04-26 10:08:57 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2017-04-26 10:08:57 +0100 |
commit | d54e56034feb0c2f51cbb37cf506788f680cc53c (patch) | |
tree | 30a5e074b1d229e8ee0da3b4bb280460a415f6f0 | |
parent | f044e6fca2354cf4e21cd1a21060b9c30b48b6a5 (diff) | |
download | appstream-glib-d54e56034feb0c2f51cbb37cf506788f680cc53c.tar.gz |
Add as_utils_guid_from_data()
This allows us to pass binary data, as well as choosing a custom namespace.
-rw-r--r-- | libappstream-glib/as-utils.c | 97 | ||||
-rw-r--r-- | libappstream-glib/as-utils.h | 4 |
2 files changed, 70 insertions, 31 deletions
diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c index e15529f..76e4dd6 100644 --- a/libappstream-glib/as-utils.c +++ b/libappstream-glib/as-utils.c @@ -1429,6 +1429,70 @@ as_ptr_array_find_string (GPtrArray *array, const gchar *value) } /** + * as_utils_guid_from_data: + * @namespace_id: A namespace ID, e.g. "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + * @data: data to hash + * @data_len: length of @data + * @error: A #GError or %NULL + * + * Returns a GUID for some data. This uses a hash and so even small + * differences in the @data will produce radically different return values. + * + * The implementation is taken from RFC4122, Section 4.1.3; specifically + * using a type-5 SHA-1 hash. + * + * Returns: A new GUID, or %NULL if the namespace_id was invalid + * + * Since: 0.6.13 + **/ +gchar * +as_utils_guid_from_data (const gchar *namespace_id, + const guint8 *data, + gsize data_len, + GError **error) +{ + gchar guid_new[37]; /* 36 plus NUL */ + gsize digestlen = 20; + guint8 hash[20]; + gint rc; + uuid_t uu_namespace; + uuid_t uu_new; + g_autoptr(GChecksum) csum = NULL; + + g_return_val_if_fail (namespace_id != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data_len != 0, FALSE); + + /* convert the namespace to binary */ + rc = uuid_parse (namespace_id, uu_namespace); + if (rc != 0) { + g_set_error (error, + AS_UTILS_ERROR, + AS_UTILS_ERROR_FAILED, + "namespace '%s' is invalid", + namespace_id); + return FALSE; + } + + /* hash the namespace and then the string */ + csum = g_checksum_new (G_CHECKSUM_SHA1); + g_checksum_update (csum, (guchar *) uu_namespace, 16); + g_checksum_update (csum, (guchar *) data, (gssize) data_len); + g_checksum_get_digest (csum, hash, &digestlen); + + /* copy most parts of the hash 1:1 */ + memcpy (uu_new, hash, 16); + + /* set specific bits according to Section 4.1.3 */ + uu_new[6] = (guint8) ((uu_new[6] & 0x0f) | (5 << 4)); + uu_new[8] = (guint8) ((uu_new[8] & 0x3f) | 0x80); + + /* return as a string */ + uuid_unparse (uu_new, guid_new); + return g_strdup (guid_new); +} + +/** * as_utils_guid_is_valid: * @guid: string to check * @@ -1471,39 +1535,10 @@ as_utils_guid_is_valid (const gchar *guid) gchar * as_utils_guid_from_string (const gchar *str) { - const gchar *namespace_id = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; - gchar guid_new[37]; /* 36 plus NUL */ - gsize digestlen = 20; - guint8 hash[20]; - gint rc; - uuid_t uu_namespace; - uuid_t uu_new; - g_autoptr(GChecksum) csum = NULL; - - /* invalid */ if (str == NULL) return NULL; - - /* convert the namespace to binary */ - rc = uuid_parse (namespace_id, uu_namespace); - g_assert (rc == 0); - - /* hash the namespace and then the string */ - csum = g_checksum_new (G_CHECKSUM_SHA1); - g_checksum_update (csum, (guchar *) uu_namespace, 16); - g_checksum_update (csum, (guchar *) str, (gssize) strlen (str)); - g_checksum_get_digest (csum, hash, &digestlen); - - /* copy most parts of the hash 1:1 */ - memcpy(uu_new, hash, 16); - - /* set specific bits according to Section 4.1.3 */ - uu_new[6] = (guint8) ((uu_new[6] & 0x0f) | (5 << 4)); - uu_new[8] = (guint8) ((uu_new[8] & 0x3f) | 0x80); - - /* return as a string */ - uuid_unparse (uu_new, guid_new); - return g_strdup (guid_new); + return as_utils_guid_from_data ("6ba7b810-9dad-11d1-80b4-00c04fd430c8", + str, strlen (str), NULL); } /** diff --git a/libappstream-glib/as-utils.h b/libappstream-glib/as-utils.h index b9037f5..bf051f6 100644 --- a/libappstream-glib/as-utils.h +++ b/libappstream-glib/as-utils.h @@ -124,6 +124,10 @@ gint as_utils_vercmp (const gchar *version_a, const gchar *version_b); gboolean as_utils_guid_is_valid (const gchar *guid); gchar *as_utils_guid_from_string (const gchar *str); +gchar *as_utils_guid_from_data (const gchar *namespace_id, + const guint8 *data, + gsize data_len, + GError **error); gchar *as_utils_version_from_uint32 (guint32 val, AsVersionParseFlag flags); gchar *as_utils_version_from_uint16 (guint16 val, |