我有一个旧的django应用程序,它在数据库中保存了UTF-8字符串,当我尝试在Ruby中获取它们时,它们看起来像无效的utf8。
保存前的字符串在python中的类型为str
,但是当从数据库中获取时,django正在给我一个正确的unicode
字符串。当我在rails中获取相同的记录时,我得到一个与python的str
字符串相同的字节序列,ruby抱怨它是一个无效的字节序列。
示例:测试过的字符串是一个表情符号:
- str
类型,序列:[237, 160, 189, 237, 180, 165]
从Django中的db获取 - unicode
类型,序列[55357, 56613]
从Rails中的db中获取 - 序列[237, 160, 189, 237, 180, 165]
有没有办法将Ruby中的字节序列转换为正确的utf8字符串?
答案 0 :(得分:2)
我无法解决您的问题,但我可以解释该字节序列。你拥有的是UTF-8编码的UTF-16。
237, 160, 189
和237, 180, 165
都是3字节的UTF-8序列:
1110xxxx 10xxxxxx 10xxxxxx
(x
&#39}是相关位) ...分别转换为代码点55357
和56613
:(或{16}中的0xD83D
和0xDD25
[237, 160, 189, 237, 180, 165].map { |b| b.to_s(2) }
#=> ["11101101", "10100000", "10111101", "11101101", "10110100", "10100101"]
# ^^^^ ^^^^^^ ^^^^^^ ^^^^ ^^^^^^ ^^^^^^
[0b1101_100000_111101, 0b1101_110100_100101]
#=> [55357, 56613]
不幸的是,这些代码点在UTF-8中无效。那是因为它们实际上是UTF-16字节:
[55357, 56613].pack('S>2').encode('utf-8', 'utf-16be')
#=> ""