Shell代表二进制

时间:2016-03-18 21:47:00

标签: elixir

我有以下声明

iex(5)> a = <<3>>
<<3>>
iex(6)> b = <<a::binary>>
<<3>>

第一行,我创建了一个值为3的二进制文件。在第三行我希望shell显示00000011而不是3.我知道首先创建一个二进制文件(1.line)然后再转换为二进制文件没有意义。但我期待shell显示00000011而不是3。

当二进制像浮动一样

iex(7)> a = << 5.3 :: float  >>
<<64, 21, 51, 51, 51, 51, 51, 51>>

我不明白,为什么它会告诉我这个数字?

1 个答案:

答案 0 :(得分:4)

Binary是内存中的字节序列。打印的表示符合此定义。打印输出中的每个数字都在0到255之间(这些数字可以表示所有可能的字节值)。

二进制文件是一种很酷且简单的方法,可以解析和编码要通过网络发送到外部系统的协议或其他消息。例如,这段代码解析ip协议:

<< protocol_version :: size(4),
   size_in_words :: size(4),
   tos :: size(8),
   total_length :: size(16),
   identifier :: size(16),
   flags :: size(3),
   fragment_offs :: size(13),
   ttl :: size(8),
   protocol :: size(8),
   header_checksum :: size(16),
   src_ip :: size(32),
   dst_ip :: size(32),
   options :: size(32),
   data :: binary >> = bits

您可以匹配二进制文件的不同部分。 size以位为单位指定。最后一部分可以没有大小,但它需要可以被8整除(它必须是n个完整字节)。

不太复杂的例子可能是128号,二进制为10000000。

iex(1)> bin = <<128>>
<<128>>
iex(2)> <<a::size(2), b::size(6)>> = bin
<<128>>
iex(3)> a # a matched bits 10, which is 2
2
iex(4)> b # b matched bits 000000 which is 0
0

可以使用相同的语法从部件创建二进制文件。允许重用变量a和b,但将它们放在不同的地方。

iex(5)> anotherbin = <<a::size(5), b::size(3)>>
<<16>>

现在第一部分是00010,第二部分是000,它给出00010000,这是16。另一件事是你可以用浮点数等整数来创建二进制文件,所以

iex(6)> a = << 5.3 :: float  >>
<<64, 21, 51, 51, 51, 51, 51, 51>>

创建另一个具有浮点值编码的二进制文件。您现在可以通过网络发送它并在另一侧解码它。所以它与你的想法相反。它不是二进制的float,而是float作为二进制文件。

要实际查看内容的二进制表示,请尝试使用来自不同模块的to_string方法。它们具有可选参数,您可以在其中打印输出。

iex(7)> Integer.to_string(128, 2)
"10000000"

还有一个问题。 Elixir中的字符串实际上是二进制文件。 shell检查所有字节是否都是可打印字符。如果是,则将它们打印为字符串

iex(20)> <<100>>
"d"

如果需要,您可以强制IO.inspect打印二进制文件作为字节或字符串列表:

iex(29)> IO.inspect <<100>>, [{:binaries, :as_binaries}]
<<100>> #this is what IO.inspect printed
"d"     #this is a return value, which is the same, but printed as string

如果强制将不可打印的字符解释为字符串,则会对其进行转义:

iex(31)> IO.inspect <<2>>, [{:binaries, :as_strings}]
"\x02" #this is what IO.inspect printed
<<2>>  #return value printed by shell