我的程序是二进制协议的解码器。该二进制协议中的一个字段是编码的String
。 String
中的每个字符都是可打印的,并且代表一个整数值。根据我正在解码的协议的规范,它所代表的整数值取自下表,其中列出了所有可能的字符:
Character Value
========= =====
0 0
1 1
2 2
3 3
[...]
: 10
; 11
< 12
= 13
[...]
B 18
例如,字符=
代表一个整数13
。
我的代码最初使用ord
来获取角色的ASCII代码,然后从中减去48
,如下所示:
def Decode(val)
val[0].ord - 48
end
假设val
仅由该表中列出的字符组成(这在其他地方得到验证),......完美运行。
然而,在another question中,有人告诉我:
你要求使用Ruby方式来使用ord,使用它的方法是反对的 Ruby方式。
在我看来,ord
正是我在这里所需要的,所以我不明白为什么在这里使用ord
不是Rubyist方式来做我想做的事。 / p>
所以我的问题是:
首先,Rubyist在上面编写我的函数的方法是什么?
辅助,为什么在这里使用ord
非Rubyist练习?
关于编码的注意事项:我正在解码的这个协议精确指定这些字符串是ASCII编码的。这里没有其他编码可行。像我这样的协议在我的行业(股票和商品市场)中非常普遍。
答案 0 :(得分:4)
我认为将字符串解码为整数数组的Rubyistic方法更快,是unpack
方法:
"=01:".unpack("C*").map {|v| v - 48}
>> [13, 0, 1, 10]
unpack
方法,"C*"
参数,将每个字符转换为8位无符号整数。
答案 1 :(得分:1)
在您的情况下,ord
可能是完全安全和适当的,因为源数据应始终以相同的方式编码。特别是如果在读取数据时将编码设置为'US-ASCII'
(尽管使用的格式对于'ASCII-8BIT','UTF-8'和'ISO-8859'来说是安全的,这可能是它的重点 - 它似乎对许多转换具有弹性,并且不使用所有可能的字节值)。但是,ord
意图与字符语义一起使用,从技术上讲,您需要字节语义。对于基本的ASCII和变体,没有实际的区别,所有低于128的字节值都是相同的字符代码。
我建议使用String#unpack
作为将二进制输入转换为Ruby数据类型的通用方法,但是没有unpack
代码用于“将此字节与偏移量一起使用”,因此它变为两部分过程。