ruby Array#pack String#unpack 实例

Posted by wxianfeng Sat, 26 May 2012 21:25:00 GMT

最近项目中常用到 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] 

http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-pack
http://www.ruby-doc.org/core-1.9.3/String.html#method-i-unpack
http://www.cnblogs.com/baochun968/archive/2011/10/19/2218008.html

This entry was posted on Sat, 26 May 2012 21:25:00 GMT and Posted in . You can follow any any response to this entry through the Atom feed. You can leave a comment or a trackback from your own site.

Tags , , , ,


Trackbacks

Use the following link to trackback from your own site:
http://wxianfeng.com/trackbacks?article_id=238

Comments

  1. Avatar
    tap over {{count}} years ago:

    请教下[“[www.wxianfeng.com]欢迎您注册,请您激活&#8221;].pack(&#8220;m&#8221;)
    后生成的 “W3d3dy53eGlhbmZlbmcuY29tXeasoui/juaCqOazqOWGjCzor7fmgqjmv4Dm\ntLs=\n” 通过unpck(“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&#8221;] 如何转换为汉字呢?

  2. Avatar
    More Info over {{count}} years ago:

    Hi mates, how is all, and what you wish for to say about this piece of writing,
    in my view its in fact awesome designed for me.

  3. Avatar
    More Info over {{count}} years ago:

    Hi mates, how is all, and what you wish for to say
    about this piece of writing, in my view its in fact awesome designed for me.

  4. Avatar
    get More Info over {{count}} years ago:

    It’s genuinely very complex in this active life to listen news on Television, therefore I only use internet
    for that purpose, and take the latest news.

  5. Avatar
    get More Info over {{count}} years ago:

    It’s genuinely very complex in this active life
    to listen news on Television, therefore I only use internet for that purpose, and take the latest
    news.

Leave a comment