pack(aTemplateString) -> aBinary
根据模板字符串的指令将数组元素打包进一个二进制序列,返回结果是一个二进制的字符串,指令后可以跟一个数字,用于指示结果集的宽度,比如A3,a3,Z3。但是对于不同的指令,其后跟随的数值所表示的含义也不同,可以结合Array#pack方法的文档给出的表格来参考:
integer整数指令(对应数组元素是整数的情况):
Integer | Array | |
---|---|---|
Directive | Element | Meaning |
C | 8位无符号整数 | |
S | 16位无符号 | |
L | 32位无符号 | |
Q | 64位无符号 | |
c | 8位有符号整数(有符号字符) |
字符串(对应数组元素是字符串的情况):
String | Array | |
---|---|---|
Directive | Element | Meaning |
A | 二进制字符串字面值(以空格填充,数值表示宽度,这个宽度就是表示结果集的字符数,如果大于元素的字符长度的,则填充空格,如果小于则截取数组元素的宽度数来处理) | |
a | 和A类似,以null来填充 | |
Z | 和a类似,以*填充 | |
H | 64位无符号 | |
m | base64编码处理(如果数值为0,不会填充行,数值指定在每个LF之间的输入字节数,向下四舍五入最低为3) |
应用场景:
字节转二进制序列进而打印字符:
ruby中字符串可以调用bytes方法获取字节数值组成的数组:
"我".bytes # => [230, 136, 145]
因为汉字在utf8中是由3个字节组成的,这里返回了三个字节的ascii对应的数值。
而若想通过这样的字节数值数组反向推到出字符是什么就可以使用pack方法:
puts [230, 136, 145].pack("c*") # => 我
根据前面的表格,c对应的指令含义是8位有符号整数(8位刚好也是一个字节的数值),*则表示处理后面所有的数组元素,并将结果拼接在一起成为一个二进制字符串返回,所以这里的返回结果是:
[230, 136, 145].pack("c*") # => "\xE6\x88\x91"
这就是一个完整的二进制序列了,至于utf8是怎么解析的,可以参考:
https://zh.wikipedia.org/wiki/UTF-8