【发布时间】:2014-06-19 02:28:02
【问题描述】:
下面代码返回的值是"\x88\x90r\"\x9EN\xFFR":
MyApp::XVP::xvp_password_encrypt_vnc("L1UkDr]c")
# => "\x88\x90r\"\x9EN\xFFR"
当我们在测试中使用它时:
should "correctly encrypt a vnc password" do
assert MyApp::XVP::xvp_password_encrypt_vnc("L1UkDr]c") == "\x88\x90r\"\x9EN\xFFR"
end
# => false
这是一个编码问题,我们可以通过以下操作看到:
MyApp::XVP::xvp_password_encrypt_vnc("L1UkDr]c").encoding
# => #<Encoding:ASCII-8BIT>
"\x88\x90r\"\x9EN\xFFR".encoding
# => #<Encoding:UTF-8>
因此,比较失败是有道理的,修复它的方法是在 xvp_password_encrypt_vnc 方法的末尾强制编码为 UTF,如下所示:
def xvp_password_encrypt_vnc(hex)
des = OpenSSL::Cipher::Cipher.new("des-ecb")
... etc
des.update(hex).force_encoding('UTF-8')
end
现在,我们失败的测试通过了:
should "correctly encrypt a vnc password" do
assert MyApp::XVP::xvp_password_encrypt_vnc("L1UkDr]c").force_encoding("UTF-8") == "\x88\x90r\"\x9EN\xFFR"
end
# => true
但事情似乎反过来不一样:
# This should fail
should "correctly encrypt a vnc password" do
MyApp::XVP::xvp_password_decrypt_vnc("\x88\x90r\"\x9EN\xFFR") == "L1UkDr]c"
end
# => true
上述方法失败的原因是我们再次将 ASCII-8bit 与 UTF-8 进行比较(之前失败了):
MyApp::XVP::xvp_password_decrypt_vnc("\x88\x90r\"\x9EN\xFFR").encoding
# => #<Encoding:ASCII-8BIT>
"L1UkDr]c".encoding
# => #<Encoding:UTF-8>
为什么会失败:
something encoded in ASCII 8-bit != same thing encoded in UTF-8
但是当我们走另一条路时它不会失败:
something encoding in UTF-8 == same thing encoded in ASCII 8-bit
【问题讨论】:
-
"\x88\x90r\"\x9EN\xFFR".valid_encoding?应该有助于回答您的问题。您的问题是字符串不是“以 UTF-8 编码的相同内容”,这些字节甚至不是有效的 UTF-8。但是,纯文本密码的 ASCII 和 UTF-8 编码相当于字节和字符。 -
你有什么问题?
-
@sawa,请阅读最后我问的部分:“那么为什么它会失败......但是当我们走另一条路时它不会失败”。
-
@NeilSlater 感谢它解释了很多。
标签: ruby encoding utf-8 character-encoding ascii-8bit