3

这里发生了什么?为什么==比较边的位置会改变输出?

secret == BCrypt::Password.new(BCrypt::Password.create(secret)) 
# => false 
BCrypt::Password.new(BCrypt::Password.create(secret)) == secret
# => true 
4

4 回答 4

3

这是因为 is 的返回值BCrypt::Password.new覆盖BCrypt::Password==

http://bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009

将潜在秘密与哈希进行比较。如果秘密是原始秘密,则返回真,否则返回假。

所以当secret在左边时,它的equals方法正在被使用(这是进行字符串比较),而当哈希在左边时,它实际上是在与原始秘密进行比较

于 2013-02-13T00:59:46.280 回答
1

最简单的答案是 ,==也就是说LHS#==,这==不是一个通用运算符,就像在 C 或 C++ 或 Java 中那样,而是一个在左侧对象上调用的函数。

如果不了解您的代码的更多信息,就很难准确地告诉您发生了什么。

简单来说,secret.class#==必须表现得与BCrypt::Password#==. 也许 BCrypt::Password 知道如何比较加密字符串(本身)和未加密字符串(参数),而secret如果是字符串,则不知道如何与BCrypt::Password自身进行比较。

于 2013-02-13T00:58:37.077 回答
1

BCrypt::Password 有一个 == 方法来与秘密进行比较。

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

于 2013-02-13T00:58:57.703 回答
0

Ruby 是一种面向对象的语言。在 OO 中,消息发送的接收者决定如何响应该消息。在您的情况下,两个接收器不仅是不同的对象,它们甚至是不同类型的对象。

Ruby 中有一些标准的双重调度协议,旨在确保某些运算符是对称的,但是 a)这些协议仅存在于数字上的算术运算而不是相等性,并且 b)不能保证对象遵循这些协议。

总之,在OO中,没有办法保证算子的对称性。这只是 OO 的基本属性。

于 2013-02-13T02:44:49.723 回答