这里发生了什么?为什么==
比较中的边位置会改变输出?
secret == BCrypt::Password.new(BCrypt::Password.create(secret))
# => false
BCrypt::Password.new(BCrypt::Password.create(secret)) == secret
# => true
答案 0 :(得分:3)
这是因为BCrypt::Password.new
的返回值为BCrypt::Password
,它会覆盖==
http://bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009
将潜在的秘密与哈希进行比较。如果是,则返回true 秘密是原始的秘密,否则就是假的。
所以当secret
在左边时,正在使用它的equals方法(正在进行字符串比较),而当哈希在左边时,它实际上是与原始秘密进行比较
答案 1 :(得分:1)
最简单的答案是==
是LHS#==
,也就是说,==
不是通用运算符,就像在C或C ++或Java中一样,而是一个被调用的函数在左侧的物体上。
在不了解您的代码的情况下,很难准确地告诉您发生了什么。
简单来说,secret.class#==
的行为必须与BCrypt::Password#==
不同。也许BCrypt :: Password知道如何比较加密的字符串(本身)和未加密的字符串(参数),而secret
,如果是字符串,则不知道如何将BCrypt::Password
与自身进行比较
答案 2 :(得分:1)
BCrypt ::密码有一个==方法与秘密进行比较。
BCrypt::Password.new(BCrypt::Password.create(secret)).class
=> BCrypt::Password
所以
BCrypt::Password.new(BCrypt::Password.create(secret)) == secret
=> true
另一个表达式不会在BCrypt :: Password上调用方法==,而是调用字符串上的方法。
http://bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009
答案 3 :(得分:0)
Ruby是一种面向对象的语言。在OO中,消息发送的接收者决定如何响应该消息。在您的情况下,两个接收器不仅是不同的对象,它们甚至是对象的类型。
Ruby中有一些标准的双调度协议,旨在确保某些运算符是对称的,但是a)这些协议仅存在于数字上的算术运算而不是相等,并且b)不保证对象遵循那些协议。
简而言之,在OO中,无法确保运营商的对称性。这只是OO的基本属性。