ruby Array#pack String#unpack 实例

转自:http://wxianfeng.com/2012/05/27/ruby-array-pack-string-unpack

最近项目中常用到 Array#pack, String#unpack 方法,在此总结下:

Array#pack, String#unpack 可以实现不同编码之间的处理, 可以处理字节级, bit 级的一些二进制格式.

字节编码, ruby里主要是 “\nnn” 和 “\xnn” 的形式, nnn 是八进制数字, nn 是十六进制, 可以从 <<ruby编程语言>> 这本书看到相关信息.

截了张书中的图:

例子:
ASCII 码值: 0123456789
字节编码: 
“\000\001\002\003\004\005\006\007\010\011” (八进制)
“\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09” (十六进制)

另外 ascii 码值是 7,8,9 的在ruby中是转义序列 “\a”, “\b”, “\t”, 所以字节编码也可以写成
\x00\x01\x02\x03\x04\x05\x06\a\b\t

1.9.2p290 :198 > a = [0,1,2,3,4,5,6,7,8,9]
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1.9.2p290 :199 > a.pack("c*")
 => "\x00\x01\x02\x03\x04\x05\x06\a\b\t"
1.9.2p290 :200 > "\x00\x01\x02\x03\x04\x05\x06\a\b\t" == "\000\001\002\003\004\005\006\007\010\011"
 => true
1.9.2p290 :201 > "\011" == "\x09"
 => true
1.9.2p290 :202 > "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09" == "\000\001\002\003\004\005\006\007\010\011"
 => true

下面来看一些实例,以字符模板来讲

1, M

M         | String  | quoted printable, MIME encoding (see RFC2045)

字符串和 quoted printable 编码之间转换,常用在邮件编码中

Array#pack
ruby-1.9.2-p290 :132 > ["[www.wxianfeng.com]欢迎您注册,请您激活"].pack("M")
 => "[www.wxianfeng.com]=E6=AC=A2=E8=BF=8E=E6=82=A8=E6=B3=A8=E5=86=8C,=E8=AF=B7=\n=E6=82=A8=E6=BF=80=E6=B4=BB=\n" 

可以看到 每76个字符就多了一个 =\n , 所以如果是用在邮件的 Subject 的中的话, 应该是

["str"].pack("M").gsub(/=\n/,"")

完整的邮件Subject编码应该是 像这样:

value = ["[#{site}]请激活您的帐号"].pack("M").gsub(/=\n/, "")
subject = "=?UTF-8?Q?#{value}?="
String#unpack
ruby-1.9.2-p290 :153 > "[www.wxianfeng.com]=E6=AC=A2=E8=BF=8E=E6=82=A8=E6=B3=A8=E5=86=8C,=E8=AF=B7=\n=E6=82=A8=E6=BF=80=E6=B4=BB=\n".unpack("M")
 => ["[www.wxianfeng.com]\xE6\xAC\xA2\xE8\xBF\x8E\xE6\x82\xA8\xE6\xB3\xA8\xE5\x86\x8C,\xE8\xAF\xB7\xE6\x82\xA8\xE6\xBF\x80\xE6\xB4\xBB"] 

2, m

m         | String  | base64 encoded string (see RFC 2045, count is width)
             |         | (if count is 0, no line feed are added, see RFC 4648)

字符串和 Base64 编码之间转换

Array#pack
ruby-1.9.2-p290 :133 > ["[www.wxianfeng.com]欢迎您注册,请您激活"].pack("m")
 => "W3d3dy53eGlhbmZlbmcuY29tXeasoui/juaCqOazqOWGjCzor7fmgqjmv4Dm\ntLs=\n"

base64编码也可以用在邮件编码中,例如用在Subject中就是这样:

value = ["[#{site}]请激活您的帐号"].pack("M").gsub(/=\n/, "")
subject = "=?UTF-8?B?#{value}?="
String#unpack
ruby-1.9.2-p290 :155 > "W3d3dy53eGlhbmZlbmcuY29tXeasoui/juaCqOazqOWGjCzor7fmgqjmv4Dm\ntLs=\n".unpack("m")
 => ["[www.wxianfeng.com]\xE6\xAC\xA2\xE8\xBF\x8E\xE6\x82\xA8\xE6\xB3\xA8\xE5\x86\x8C,\xE8\xAF\xB7\xE6\x82\xA8\xE6\xBF\x80\xE6\xB4\xBB"]

3, L

 L         | Integer | 32-bit unsigned, native endian (uint32_t)

整型(ASCII)和二进制字符串相互转化,int是32为无符号的,占4个字节

Array#pack
ruby-1.9.2-p290 :139 > [65].pack("L")
 => "A\x00\x00\x00"

String#unpack
ruby-1.9.2-p290 :140 > "A\x00\x00\x00".unpack("L")
 => [65] 

4, c

c         | Integer | 8-bit signed (signed char)

整型(ASCII)和二进制字符串相互转化,int 是8位有符号的,占一个字节

Array#pack
ruby-1.9.2-p290 :142 > [77].pack("c")
 => "M" 

String#unpack
ruby-1.9.2-p290 :143 > "M".unpack("c")
 => [77] 

5, Q

Q         | Integer | 64-bit unsigned, native endian (uint64_t)

整型和二进制字符串相互转化,int是64位无符号的,占8字节

Array#pack
ruby-1.9.2-p290 :149 > [1338053358065].pack("Q")
 => "\xF1\xF11\x8A7\x01\x00\x00" 

String#unpack
ruby-1.9.2-p290 :150 > "\xF1\xF11\x8A7\x01\x00\x00".unpack("Q")
 => [1338053358065]

6, S

S         | Integer | 16-bit unsigned, native endian (uint16_t)

整型和二进制字符串转化,int是16位无符号的,占2个字节

Array#pack
ruby-1.9.2-p290 :151 > [6].pack("S")
 => "\x06\x00" 

String#unpack
ruby-1.9.2-p290 :152 > "\x06\x00".unpack("S")
 => [6] 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值