Ruby相当于Node .toString('ascii')

时间:2018-11-14 18:07:20

标签: node.js ruby

我正在努力将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 = ???

我已经尝试了服务器方面的事情,几乎是所有解压缩选项,并且也尝试使用了编码功能,但是我对这里的问题缺乏了解。

1 个答案:

答案 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}}一无所有。