我正在努力将Node应用程序转换为Ruby。我有一个整数缓冲区,需要将其编码为ASCII字符串。
在Node中,这是这样完成的:
const a = Buffer([53, 127, 241, 120, 57, 136, 112, 210, 162, 200, 111, 132, 46, 146, 210, 62, 133, 88, 80, 97, 58, 139, 234, 252, 246, 19, 191, 84, 30, 126, 248, 76])
const b = a.toString('hex')
// b = "357ff178398870d2a2c86f842e92d23e855850613a8beafcf613bf541e7ef84c"
const c = a.toString('ascii')
// c = '5qx9\bpR"Ho\u0004.\u0012R>\u0005XPa:\u000bj|v\u0013?T\u001e~xL'
我想在Ruby中获得相同的输出,但是我不知道如何将a
转换为c
。我使用b
来验证a
在Ruby和Node中的解析方式是否相同,并且看起来可以正常工作。
a = [53, 127, 241, 120, 57, 136, 112, 210, 162, 200, 111, 132, 46, 146, 210, 62, 133, 88, 80, 97, 58, 139, 234, 252, 246, 19, 191, 84, 30, 126, 248, 76].pack('C*')
b = a.unpack('H*')
# ["357ff178398870d2a2c86f842e92d23e855850613a8beafcf613bf541e7ef84c"]
# c = ???
我已经尝试了服务器方面的事情,几乎是所有解压缩选项,并且也尝试使用了编码功能,但是我对这里的问题缺乏了解。
答案 0 :(得分:2)
好吧,我对Node.js并不熟悉,但是您可以从一些基本的理解中获得相当的了解:
节点状态:
'ascii'-仅适用于7位ASCII数据。这种编码速度很快,如果已设置,则会去除高位。
更新重新阅读nod.js描述后,我认为这只是意味着它将下降127并且仅关注前7位,因此可以简化为:
def node_js_ascii(bytes)
bytes.map {|b| b % 128 }
.reject(&127.method(:==))
.pack('C*')
.encode(Encoding::UTF_8)
end
node_js_ascii(a)
#=> #=> "5qx9\bpR\"Ho\u0004.\u0012R>\u0005XPa:\vj|v\u0013?T\u001E~xL"
现在唯一的区别是,node.js使用“ \ u000b”表示垂直制表符,而ruby使用“ \ v”,并且ruby将大写字符用于Unicode,而不是小写(“ \ u001E”与“ \ u001e” )(如果您选择的话,可以解决此问题)
请注意:由于您的字节数组中的字符大于8位,因此这种编码形式不可逆。
TL; DR (以前的解释和解决方案最多只能使用8位)
好的,所以我们知道最大支持的十进制为127("1111111".to_i(2)
),并且如果设置了该含义,该节点将剥离高位[我假设] 241(如果我们剥离高位,则8位数字将变为113位)
有了这种理解,我们可以使用:
a = [53, 127, 241, 120, 57, 136, 112, 210, 162, 200, 111, 132, 46, 146, 210, 62, 133, 88, 80, 97, 58, 139, 234, 252, 246, 19, 191, 84, 30, 126, 248, 76].map do |b|
b < 128 ? b : b - 128
end.pack('C*')
#=> "5\x7Fqx9\bpR\"Ho\x04.\x12R>\x05XPa:\vj|v\x13?T\x1E~xL"
然后我们可以将其编码为UTF-8
,如下所示:
a.encode(Encoding::UTF_8)
#=> "5\u007Fqx9\bpR\"Ho\u0004.\u0012R>\u0005XPa:\vj|v\u0013?T\u001E~xL"
但是这里仍然有一个问题。
当Node.js转换为'ascii'时,似乎也忽略了Delete(127)(我的意思是高位已设置,但如果我们将其剥离,则它是63(“?”),与输出),所以我们也可以解决此问题
a = [53, 127, 241, 120, 57, 136, 112, 210, 162, 200, 111, 132, 46, 146, 210, 62, 133, 88, 80, 97, 58, 139, 234, 252, 246, 19, 191, 84, 30, 126, 248, 76].map do |b|
b < 127 ? b : b - 128
end.pack('C*')
#=> "5\xFFqx9\bpR\"Ho\x04.\x12R>\x05XPa:\vj|v\x13?T\x1E~xL"
a.encode(Encoding::UTF_8, undef: :replace, replace: '')
#=> "5qx9\bpR\"Ho\u0004.\u0012R>\u0005XPa:\vj|v\u0013?T\u001E~xL"
现在,由于127-128 = -1(负符号位)在UTF-8中变为“ \ xFF”一个未定义的字符,因此我们添加了undef: :replace
,该字符未定义时该怎么做,请使用replace并添加{ {1}}一无所有。