Очистить каждый второй бит в Ruby - PullRequest
1 голос
/ 25 апреля 2019

Как очистить все остальные для строки в Ruby и преобразовать ее в байтовый массив?Я понимаю, что мне нужно сделать операцию И со значением 0x01010101 для каждого байта.Но проблема в правильном преобразовании из строки в двоичный файл.В идеале это должно быть быстро и с наименьшим количеством выделений.

Позже мне нужно будет передать это значение в Digest::MD5.hexdigest.

Ответы [ 2 ]

6 голосов
/ 25 апреля 2019

Во-первых, обратите внимание, что 0x для базы 16, 0b для базы 2:

0b11111111.to_s(2) #=> "11111111"
0x11111111.to_s(2) #=> "10001000100010001000100010001"

Поскольку вы конвертируете биты в байтах, вы хотите использовать 0b... для своей маски.

Далее

0b01010101.to_s(2) #=> "1010101" 

показывает, что, как и со всеми целыми числами, ведущие нули отбрасываются, то есть вы можете включать их или нет Рассмотрим,

0b11111111 & 0     #=> 0

Видно, что в качестве маски ноль рассматривается как имеющий 7 начальных битов нуля. Мы видим, что

(0b11111111 &
  0b1010101).to_s(2) #=> "1010101"

Итак, мы можем определить вашу побитовую маску как

MASK = 0b1010101

Теперь мы можем использовать 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] 

"C" в "C*" означает, что директива формата "C" применяется к первому символу; "*" означает повторить "C" для всех последующих символов.

См. Также Целое число # & .

Я вижу из ответа @ DavidKling, что можно написать

str.bytes.map { |u| u & MASK }
2 голосов
/ 25 апреля 2019

Вы можете использовать String#bytes, чтобы получить массив значений Unicode символов строки (в десятичном формате).

 'Roman'.bytes # [82, 111, 109, 97, 110]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...