Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Digest::UUID v5 (vs) Postgresql uuid-ossp v5

I'm getting different V5 UUIDs when generating with Rails Digest::UUID and Postgresql uuid-ossp.

Rails:

[58] pry(main)> Digest::UUID.uuid_v5('e90bf6ab-f698-4faa-9d0f-810917dea53a', 'e90bf6ab-f698-4faa-9d0f-810917dea53a')
=> "db68e7ad-332a-57a7-9638-a507f76ded93"

Postgresql uuid-ossp:

select uuid_generate_v5('e90bf6ab-f698-4faa-9d0f-810917dea53a', 'e90bf6ab-f698-4faa-9d0f-810917dea53a');
           uuid_generate_v5
--------------------------------------
 6c569b95-a6fe-5553-a6f5-cd871ab30178

What would be the reason? I thought both should generate the same UUID when the input is the same, but it is different!

like image 982
Ashok Kumar P S Avatar asked Sep 15 '25 19:09

Ashok Kumar P S


2 Answers

It seems that a patch is proposed so that working string-representation of namespaces can be enabled explicitly

  • The new behavior will be enabled by setting the config.active_support.use_rfc4122_namespaced_uuids option to true.

but, the patch is very recent and it could be still under test. People can be afraid it breaks things. Check

https://github.com/rails/rails/issues/37681 https://github.com/rails/rails/pull/37682/files

Meanwhile, a workaround is to pack the namespace string

ns=n.scan(/(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/).flatten.map { |s| s.to_i(16) }.pack("NnnnnN")

In your example

irb(main):037:0> n='e90bf6ab-f698-4faa-9d0f-810917dea53a'
=> "e90bf6ab-f698-4faa-9d0f-810917dea53a"
irb(main):038:0>  ns=n.scan(/(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/).flatten.map { |s| s.to_i(16) }.pack("NnnnnN")
=> "\xE9\v\xF6\xAB\xF6\x98O\xAA\x9D\x0F\x81\t\x17\xDE\xA5:"
irb(main):039:0> puts Digest::UUID.uuid_v5(ns, 'e90bf6ab-f698-4faa-9d0f-810917dea53a')
6c569b95-a6fe-5553-a6f5-cd871ab30178
like image 190
arivero Avatar answered Sep 18 '25 08:09

arivero


It's not an answer to the question about why Rails produces a different result, but if you want to produce v5 UUID in your Ruby code, you could use uuidtools. It returns the same result as PSQL:

  ~ pry
[1] pry(main)> require 'uuidtools'
=> true
[2] pry(main)> UUIDTools::UUID.sha1_create(UUIDTools::UUID.parse('e90bf6ab-f698-4faa-9d0f-810917dea53a'), 'e90bf6ab-f698-4faa-9d0f-810917dea53a')

=> #<UUID:0x3fe09ea60dd8 UUID:6c569b95-a6fe-5553-a6f5-cd871ab30178>
[3] pry(main)>
like image 38
Alexander Popov Avatar answered Sep 18 '25 10:09

Alexander Popov