Если вы запустите эту команду на вашем Unix
echo -n "foo" | openssl dgst -sha1
Вы получите такой вывод:
(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
(с последующим переходом на новую строку).
Как заставить openssl не показывать префикс (stdin)=
и избежать завершающего символа новой строки?
решение1
Формат raw binary не добавляет никаких посторонних выходных данных.
Вывод в виде binary, затем преобразование в hex:
echo -n "foo" | openssl dgst -sha1 -binary | xxd -p
Дам вам это:
0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
Этот метод должен быть перспективным на случай, если кто-то снова решит изменить формат текстового вывода. Я уверен, что они исправят префикс на "SHA1(stdin)= ", чтобы он соответствовал файловому вводу.
Не могу поверить, что они это изменили! Интересно, сколько скриптов было сломано.
решение2
Я наблюдаю такое поведение в OpenSSL 1.0.0e на Ubuntu 11.10, тогда как OpenSSL 0.9.8k и 0.9.8t выводят только хэш. Командная строка OpenSSL не предназначена для гибкости, это скорее быстрый и грязный способ выполнения криптографических вычислений из командной строки.
Если вы хотите использовать OpenSSL, отфильтруйте вывод:
echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //'
В Linux (с инструментами GNU или BusyBox) вы можете использоватьsha1sum
, который не требует установки OpenSSL и имеет стабильный формат вывода. Он всегда печатает имя файла, так что удалите его.
echo -n "foo" | sha1sum | sed 's/ .*//'
В системах BSD, включая OSX, вы можете использоватьsha1
.
echo -n "foo" | sha1 -q
Все они выводят контрольную сумму в шестнадцатеричном формате с последующей новой строкой. Текст в системах Unix всегда состоит из последовательности строк, и каждая строка заканчивается символом новой строки. Если вы сохраните вывод команды в переменной оболочки, последняя новая строка будет удалена.
digest=$(echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //')
Если вам необходимо передать входные данные в программу, требующую контрольную сумму без завершающего символа новой строки (что случается крайне редко), удалите символ новой строки.
echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //' | tr -d '\n' | unusual_program
решение3
Вот еще один вариант:
echo -n "foo" | openssl sha1 | awk '{print $2}'
решение4
Вот как это сделать, используя встроенные функции bash вместо pipe, awk, sed, tr, cut и т. д.:
output="$(openssl sha1 <(printf foo))"; echo ${output/* }