在 Ruby 中使用 ("C") 指令打包成字节字符串

Posted

技术标签:

【中文标题】在 Ruby 中使用 ("C") 指令打包成字节字符串【英文标题】:packing to byte string using ("C") directive in Ruby 【发布时间】:2017-04-18 18:24:56 【问题描述】:

我正在尝试使用array.pack("C") 将一个字节数组打包成一个字符串,但我得到了一些奇怪的值包。例如,当我说[7].pack("C") 时,返回值为"\a",而当我说"\x07".unpack("C") 时,返回值为[7],这是所需的行为。

例如[6].pack("C") 返回"\x06",同样是期望的结果,而[33].pack("C") 返回"!"

一般来说,我是字节和十六进制的新手。这里发生了什么?据我了解,[33].pack("C") 应该返回"\x21"

【问题讨论】:

【参考方案1】:

为什么会返回"\x21"\x 表示法是为不可打印的字符保留的,但由于 \x21 等同于 !,所以这就是显示的内容。

字符串的inspect 版本通常是它最可读 的版本,而不是最字面的。

同样:

"!".ord
# => 33
"\x21".ord
# => 33
"\x21".ord.to_s(16)
# => "21"
33.chr
# => "!"

有一些特殊字符documented in the Strings section:

\a             bell, ASCII 07h (BEL)
\b             backspace, ASCII 08h (BS)
\t             horizontal tab, ASCII 09h (TAB)
\n             newline (line feed), ASCII 0Ah (LF)
\v             vertical tab, ASCII 0Bh (VT)
\f             form feed, ASCII 0Ch (FF)
\r             carriage return, ASCII 0Dh (CR)
\e             escape, ASCII 1Bh (ESC)
\s             space, ASCII 20h (SPC)
\\             backslash, \
\nnn           octal bit pattern, where nnn is 1-3 octal digits ([0-7])
\xnn           hexadecimal bit pattern, where nn is 1-2 hexadecimal digits ([0-9a-fA-F])
\unnnn         Unicode character, where nnnn is exactly 4 hexadecimal digits ([0-9a-fA-F])
\unnnn ...   Unicode character(s), where each nnnn is 1-6 hexadecimal digits ([0-9a-fA-F])
\cx or \C-x    control character, where x is an ASCII printable character

【讨论】:

【参考方案2】:

这些字符串是完全等价的,如果完全相同的字节,它们只是不同的表示:

"\a" == "\x07"
# => true

"\x21" == "!"
# => true

如果您查看the ASCII table,您会看到十六进制 21(十进制 33)由感叹号字符表示。类似地,十六进制 7(和十进制 7)字符由称为 BEL(铃)的控制字符表示,我们通常将其表示为 "\a"

一般来说,Ruby 在打印字符串时会选择最通用的字符串表示形式。您可以在代码中使用其他(等效)表示形式。但是,总是会映射回内存中完全相同的字节。

【讨论】:

以上是关于在 Ruby 中使用 ("C") 指令打包成字节字符串的主要内容,如果未能解决你的问题,请参考以下文章

ruby中愚蠢的哈希实验

ruby中愚蠢的哈希更新实验

使用regex匹配Ruby子字符串,并像索引一样引用它

ruby在一个文件中定义的变量,如何在下一个文件中使用该变量

Swift 相当于 Ruby 的 "each_cons"

Ruby 哈希中的 : 和 "" 有啥区别?