Skip to content

Instantly share code, notes, and snippets.

@fabiolimace
Last active September 11, 2021 04:22
Show Gist options
  • Save fabiolimace/a4bea1b3eec12606f678e3cb3be3d6b0 to your computer and use it in GitHub Desktop.
Save fabiolimace/a4bea1b3eec12606f678e3cb3be3d6b0 to your computer and use it in GitHub Desktop.
Function for generating name-based MD5 UUIDs (v3) on PostgreSQL
/**
* Returns a name-based UUID v3 (MD5)
*
* RFC-4122 compliant.
*
* Tags: uuid guid uuid-generator guid-generator generator name hash md5 sha1 rfc4122 rfc-4122
*
* @param p_name a string
* @param p_namespace a UUID string
*/
create or replace function fn_uuid_name_based(p_name varchar, p_namespace varchar) returns uuid as $$
declare
v_bytes bytea;
begin
-- Decode name space UUID string to byte array
v_bytes := decode(replace(p_namespace::varchar, '-', ''), 'hex');
-- Calculate the MD5 of name space and name
v_bytes := decode(md5((v_bytes::bytea || p_name::bytea)), 'hex');
-- Set version bits (0011)
v_bytes := set_bit(v_bytes, 55, 0);
v_bytes := set_bit(v_bytes, 54, 0);
v_bytes := set_bit(v_bytes, 53, 1);
v_bytes := set_bit(v_bytes, 52, 1);
-- Set variant bits (10xx)
v_bytes := set_bit(v_bytes, 71, 1);
v_bytes := set_bit(v_bytes, 70, 0);
return encode(v_bytes, 'hex')::uuid;
end $$ language plpgsql;
/**
* Returns a name-based UUID v3 (MD5)
*
* RFC-4122 compliant.
*
* Tags: uuid guid uuid-generator guid-generator generator name hash md5 sha1 rfc4122 rfc-4122
*
* @param p_name a string
*/
create or replace function fn_uuid_name_based(p_name varchar) returns uuid as $$
declare
begin
return fn_uuid_name_based(p_name, ''::varchar);
end $$ language plpgsql;
-- EXAMPLE 1:
-- select fn_uuid_name_based('John Smith', '58988cc4-bbab-48a2-94f4-d23807e3b73c');
-- EXAMPLE 1 OUTPUT:
-- d89c2dfb-96e1-3ce8-bee8-9cc44149c95f
-- EXAMPLE 2:
-- select fn_uuid_name_based('John Smith');
-- EXAMPLE 2 OUTPUT:
-- 6117323d-2cab-3c17-944c-2b44587f682c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment