pack()和unpack()如何在Ruby中工作

在Ruby中为什么我们需要数组Packingdirective如何帮助做这样的包装?

我在我的控制台中运行了一些代码来查看Array包装中的指令是什么以及如何。但是输出与每个指令非常相似。 然后在核心他们如何不同?

 irb(main):003:0> n = [ 65, 66, 67 ] => [65, 66, 67] irb(main):004:0> n.pack("ccc") => "ABC" irb(main):005:0> n.pack("C") => "A" irb(main):006:0> n.pack("CCC") => "ABC" irb(main):007:0> n.pack("qqq") => "A\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x00\ x00\x00\x00" irb(main):008:0> n.pack("QQQ") => "A\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x00\ x00\x00\x00" irb(main):009:0> n.pack("SSS") => "A\x00B\x00C\x00" irb(main):010:0> n.pack("sss") => "A\x00B\x00C\x00" irb(main):011:0> 

现在我可以从控制台看到n.pack("SSS") and n.pack("sss");n.pack("ccc") and n.pack("CCC"); n.pack("qqq") and n.pack("QQQ") n.pack("SSS") and n.pack("sss");n.pack("ccc") and n.pack("CCC"); n.pack("qqq") and n.pack("QQQ")给出相同的输出。 然后差异在哪里?

文档也没有涵盖每个指令在现实生活中如何工作的一些例子。 我也对下面的指令感到困惑,因为我不知道如何测试它们? 任何带有它们的小代码对我都有帮助:

  • S_, S!
  • S> L> Q>
  • S!< I!<
  • L_, L!

您在询问有关计算机如何在内存中存储数字的基本原则的问题。 例如,您可以查看这些以了解更多信息:

http://en.wikipedia.org/wiki/Computer_number_format#Binary_Number_Representation
http://en.wikipedia.org/wiki/Signed_number_representations

作为一个例子,取Ss之间的差异; 两者都用于打包和解包16位数字,但一个用于有符号整数,另一个用于无符号整数。 当您想要将字符串解包回原始整数时,这具有重要意义。

S :16位无符号表示数字0 – 65535(0 – (2 ^ 16-1))
s :16位有符号整数-32768 – 32767( – (2 ^ 15) – (2 ^ 15-1))(一位用于符号)

差异可以在这里看到:

 # S = unsigned: you cannot pack/unpack negative numbers > [-1, 65535, 32767, 32768].pack('SSSS').unpack('SSSS') => [65535, 65535, 32767, 32768] # s = signed: you cannot pack/unpack numbers outside range -32768 - 32767 > [-1, 65535, 32767, 32768].pack('ssss').unpack('ssss') => [-1, -1, 32767, -32768] 

所以你看到你必须知道如何在计算机内存中表示数字才能理解你的问题。 有符号数字使用一位来表示符号,而无符号数字不需要这个额外位,但是你不能代表负数。

这是数字如何在计算机存储器中表示为二进制的基础。

例如,您需要打包的原因是您需要将数字作为字节流从一台计算机发送到另一台计算机(例如通过网络连接)。 您必须将整数编号打包为字节才能通过流发送。 另一种选择是将数字作为字符串发送; 然后你将它们编码并解码为两端的字符串,而不是打包和解包。

或者假设您需要在Ruby的系统库中调用C函数。 用C编写的系统库在基本整数(int,uint,long,short等)和C-structures(struct)上运行。 在调用此类系统方法之前,您需要将Ruby整数转换为系统整数或C结构。 在那些情况下, packunpack可用于接口这样的方法。


关于附加指令,它们处理如何表示压缩字节序列的字节顺序。 请参阅此处有关endianness的含义及其工作原理:

http://en.wikipedia.org/wiki/Endianness

简单来说,它只是告诉包装方法整数应该转换成字节的顺序:

 # Big endian > [34567].pack('S>').bytes.map(&:to_i) => [135, 7] # 34567 = (135 * 2^8) + 7 # Little endian > [34567].pack('S<').bytes.map(&:to_i) => [7, 135] # 34567 = 7 + (135 * 2^8) 
Interesting Posts