Ruby中的pack()和unpack()如何工作 [英] How does pack() and unpack() work in Ruby

查看:487
本文介绍了Ruby中的pack()和unpack()如何工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Ruby中,为什么需要数组 Packing ? directive 如何帮助进行此类打包?

In Ruby why we need array Packing? How does directive help to do such packing?

我在控制台中运行了一些代码,以查看指令在Array中的外观和方式 包装.但是输出与每个指令都非常相似.那么在核心方面它们有何不同?

I ran some code in my console to see what and how directives looks like in Array packing.But the output is closely same with each directives. Then in core how they differs?

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")提供相同的输出.那么区别在哪里?

Now I can see from the console that n.pack("SSS") and n.pack("sss");n.pack("ccc") and n.pack("CCC"); n.pack("qqq") and n.pack("QQQ") gives the same output. Then where the differences are?

并且文档也没有涵盖每个指令如何在现实生活中的程序中运行的示例. 我也对以下指令感到困惑,因为我不知道如何对其进行测试?任何小的代码 它们对我也有帮助:

And the docs also not covered a bit of example of how each directive works on in real life program. I am also confused with the below directives as i don't know how to test them? any small code with them also helpful for me:

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

推荐答案

您在问一个有关计算机如何在内存中存储数字的基本原理的问题.例如,您可以查看以下内容以了解更多信息:

You are asking a question about the fundamental principles of how computers store numbers in memory. For example you can look at these to learn more:

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

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

As an example take the difference between S and s; both are used for packing and unpacking 16-bit numbers, but one is for signed integers and the other for unsigned. This has significant meaning when you want to unpack the string back into the original integers.

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

S: 16-bit unsigned means numbers 0 - 65535 (0 - (2^16-1))
s: 16-bit signed integer numbers -32768 - 32767 (-(2^15) - (2^15-1)) (one bit used for sign)

可以在这里看到区别:

# 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]

因此,您必须知道计算机内存中的数字表示方式才能理解您的问题.带符号的数字用一位表示符号,而无符号的数字不需要这多余的一位,但是您不能再用负数表示.

So you see you have to know how numbers are represented in computer memory in order to understand your question. Signed numbers use one bit to represent the sign, while unsigned numbers do not need this extra bit, but you cannot represent negative numbers then.

这是如何在计算机内存中将数字表示为二进制的最基本的方法.

This is the very basic of how numbers are represented as binary in computer memory.

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

The reason you need packing for example is when you need to send numbers as a byte stream from one computer to another (like over a network connection). You have to pack your integer numbers into bytes in order to be sent over a stream. The other option is to send the numbers as strings; then you encode and decode them as strings on both ends instead of packing and unpacking.

或者说您需要从Ruby调用系统库中的C函数.用C编写的系统库在基本整数(int,uint,long,short等)和C结构(struct)上运行.在调用此类系统方法之前,您需要将Ruby整数转换为系统整数或C结构.在这种情况下,可以使用packunpack来连接这些方法.

Or let's say you need to call a C-function in a system library from Ruby. System libraries written in C operate on basic integers (int, uint, long, short, etc.) and C-structures (struct). You will need to convert your Ruby integers into system integers or C-structures before calling such system methods. In those cases pack and unpack can be used to interface which such methods.

关于其他指令,它们处理如何表示压缩字节序列的字节序.在这里查看字节序的含义及其工作原理:

Regarding the additional directives they deal with the endianness of how to represent the packed byte sequence. See here on what endianness means and how it works:

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

简而言之,它只是告诉打包方法将整数转换为字节的顺序:

In simplified terms it just tells the packing method in which order the integers should be converted into bytes:

# 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)

这篇关于Ruby中的pack()和unpack()如何工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆