Массив байтов (может содержать специальный символ) в Bash

#arrays #bash #base64

#массивы #bash #base64

Вопрос:

Декодируйте сообщение (может содержать специальный символ) с помощью base64 из Bash. Сохранение в файл даст 48 байт данных. Тем не менее, при передаче его в переменную он становится строкой в 41 байт. Я считаю, что это вызвано способом обработки специальных символов Bash (^@).

В качестве примера,

 meow_bash=`printf $variable | base64 --decode`
echo ${#meow_bash}  # return 41

printf $variable | base64 --decode > meow
wc -c meow # return 48
  

Теперь, если я не хочу сохранять массив в файл из-за конфиденциального характера данных. Для этого мне также нужно использовать сценарий оболочки. Есть ли у меня способ использовать bash / sh для его успешной передачи?

Комментарии:

1. ^@ является нулевым байтом и не может быть сохранен как переменная bash или передан в качестве аргумента какой-либо программе. Не используйте bash для двоичных данных. Вы можете сохранить base64 и конвертировать его всякий раз, когда вы записываете его во что-то.

2. IIRC Я также видел, как bash (я думаю, что это была старая версия) запутался в символах удаления (hex 7f). И в зависимости от локали некоторые инструменты могут отказаться работать, например, с последовательностями, которые не являются допустимыми UTF-8, и… Из-за этого инструменты оболочки, которые работают с двоичными данными, будут либо принимать их в base64 (или hex или что-то подобное), либо через каналы.

Ответ №1:

Пожалуйста, научитесь указывать свои расширения: используйте printf "$variable" , а не printf $variable

Простейшей причиной этого является то, что c определяет переменную как заканчивающуюся нулевым байтом.
Поэтому строка c не может содержать нулевой байт.
Bash (написанный на c) автоматически удаляет любое нулевое значение внутри переменных.

Но может работать с нулевыми байтами в потоках (каналах и т.п.).

Простой обходной путь — не сохранять значения (после декодирования) внутри переменных.

Также обратите внимание, что переменная может содержать любое байтовое значение при хранении в кодировке base64.

Таким образом, переменной может быть присвоено безопасное значение в кодировке base64:

При использовании значения переменной в канале не стирается ни один байт:

 $ variable="YWoAa2hzZ2RrAGxzawBmZGp2"
$ printf '%s' "$variable" | base64 --decode | wc -c
18
  

То есть: поток может содержать байты с нулевым значением.

Но присвоение декодированного значения переменной:

 $ variable="YWoAa2hzZ2RrAGxzawBmZGp2"
$ meow_bash="$(printf '%s' "$variable" | base64 --decode)"
$ printf '%s' "$meow_bash" | wc -c
15
$ echo "${#meow_bash}"
15
  

Переменная $meow_bash потеряла 3 нулевых байта.

Комментарии:

1. Я предполагаю, что сообщение take home будет следующим: никогда не назначайте какой-либо массив байтов непосредственно переменной bash, несмотря ни на что…