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

时间:2019-03-15 02:11:18

标签: ruby-on-rails postgresql uuid

使用Rails Digest :: UUID和Postgresql uuid-ossp生成时,我得到了不同的V5 UUID。

路轨:

// Procotols
protocol Message {

}

protocol Socket {
    associatedtype T: Message
    var messages: [T] { get }
}

// Real implementation
class RealMessage: Message {

}

class RealSocket: Socket {
    private(set) var messages: [RealMessage] = []
}

// Mocks
class MockMessage: Message {

}

class MockSocket: Socket {
    private(set) var messages: [MockMessage] = []
}

class VC {
    // Error here: Protocol 'Socket' can only be used as a generic constraint because it has Self or associated type requirements
    var socket: Socket = MockSocket()

    // The only way I know to solve this is using the codes below:
    // var socket: MockSocket = MockSocket()
}

PostgreSQL uuid-ossp:

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

这是什么原因?我认为当输入相同但两者不同时,两者都应生成相同的UUID!

2 个答案:

答案 0 :(得分:1)

似乎提出了一个补丁程序,以便可以显式启用名称空间的工作字符串表示形式

  • 通过将config.active_support.use_rfc4122_namespaced_uuids选项设置为 true

但是,该补丁程序是最新的,可能仍在测试中。人们可能会担心它会破坏事情。检查

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

同时,一种解决方法是打包名称空间字符串

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

在您的示例中

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

答案 1 :(得分:0)

这不是关于Rails为什么会产生不同结果的问题的答案,但是如果您想在Ruby代码中产生v5 UUID,则可以使用uuidtools。它返回与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)>