清除Ruby中的所有其他内容

Rom*_*kin 1 ruby bit-manipulation

如何在Ruby中彼此清除字符串,然后将其转换为字节数组?我了解我需要对每个字节使用0x01010101值进行AND操作。但是困难在于如何正确地将字符串转换为二进制。理想情况下,它应该快速并且分配的数量最少。

稍后,我将需要将此值传递给Digest::MD5.hexdigest

Car*_*and 6

首先,请注意0x以16 0b为底数是2:

0b11111111.to_s(2) #=> "11111111"
0x11111111.to_s(2) #=> "10001000100010001000100010001"
Run Code Online (Sandbox Code Playgroud)

在转换字节内的位时,要0b...用于掩码。

下一个,

0b01010101.to_s(2) #=> "1010101" 
Run Code Online (Sandbox Code Playgroud)

表明与所有整数一样,前导零被删除,这意味着您可以包含或不包含它们。考虑,

0b11111111 & 0     #=> 0
Run Code Online (Sandbox Code Playgroud)

可以看出,作为掩码,零被视为具有7个零的前导位。我们看到

(0b11111111 &
  0b1010101).to_s(2) #=> "1010101"
Run Code Online (Sandbox Code Playgroud)

因此,我们可以将您的按位掩码定义为

MASK = 0b1010101
Run Code Online (Sandbox Code Playgroud)

现在,我们可以将String#unpack与格式字符串"C*"一起使用,以将字符串转换为8位无符号整数的数组,然后将其按位MASK(使用&):

str = "Let's party, now!"
str.unpack("C*").map { |u| u & MASK }
  #=> [68, 69, 84, 5, 81, 0, 80, 65, 80, 84, 81, 4, 0, 68, 69, 85, 1] 
Run Code Online (Sandbox Code Playgroud)

"C""C*"装置中的格式指令"C"被施加到第一个字符; "*"表示"C"对所有后续字符重复。

另请参阅Integer#&

我从@DavidKling的答案中看到,有人可以选择写

str.bytes.map { |u| u & MASK }
Run Code Online (Sandbox Code Playgroud)