KEEP K.I.S.S.

tk's blog

Ruby的字节操作

一个字节其实也就是一个整数,如果用十六进制表示的话,正好是两个十六进制数,用字符串表示就是 “HH”这样的表示。

Ruby的字节操作主要是靠两个方法来实现,String#unpack 和 Array#pack,两个类的实例方法,参数均为单一字符串。

举一个例子来讲解。

一般的 32位 Little-endian 机器上的单精度浮点数 float的一个实例: f = 88.888,得到它的字节表示 =>

因为字节操作需要 Array 类的 pack 操作,所以先把 f 放入一个数组实例中

 

irb(main):001:0> f = 88.888
=> 88.888
irb(main):002:0> s = []
=> []
irb(main):003:0> s << f
=> [88.888]
irb(main):004:0>

然后需要 pack 得到字符串表示

 

irb(main):004:0> s.pack("F")
=> "\xA8\xC6\xB1B"

也许会奇怪这个字符串为什么会这样,其实这里是 "\xA8\xC6\B1\x42",因为 \x42 正好是ASCII码表中 'B' 的十六进制代码,所以这里会显示成这样连着的。

然后我们得到字节的数值表示和十六进制表示:

 

irb(main):005:0> s.pack("F").unpack("C*")
=> [168, 198, 177, 66]
irb(main):006:0> s.pack("F").unpack("H*")
=> ["a8c6b142"]

还有一种方式:

 

irb(main):007:0> s.pack("F").unpack("C*").collect {|x| x.to_s(16) }
=> ["a8", "c6", "b1", "42"]

其实难点在于 pack 和 unpack 的操作,这个参数会很多,理解起来也有点难度,我觉得还是多用用就比较好理解了。

命令行、脚本化、自动化以及其他

昨晚一个同学问了我一个问题,他跟着导师做项目,问为什么以及怎么去解析特定样式的命令行参数,比如

./DT -r rrr.txt -t ttt.txt -p 0 -s 5 

这里明显是为了脚本化和自动化用的,具体解析就不讲了,其实命令行参数设置可以参考 GNU 风格,比如上面的这个就可以写作

./DT -r,rrr.txt -t,ttt.txt -p,0 -s,5 

GNU 风格的好处在于明辨,参数项和参数值在同一个字符串中,用逗号分隔,进行解析时候就简便一些。命令行的函数好处在于便于使用管道(PIPE)和脚本来实现自动化,避免低效的手工和重复。

这段时间自己在看《程序员修炼之道》,非常好的一本书,感觉到自己有好多的不足,至少从怎么做一个卓有成效的程序员,来讲,我并没有明显的使用脚本去自动化去做一些事情,总是依赖GUI和手工。。。。

其实讲的很多内容并不是局限在编程这个领域,书中也是这么说的,学以致用,卓有成效的手段在各个领域都会有所用处。看来自己还是得不断努力了,不要再愚昧愚蠢的手工重复。。。。。

此书强烈推荐。