openssl
's stdin is a byte stream.
The contents of $user
is a sequence of non-0 bytes (which may or may not form valid characters in UTF-8 or other character set/encoding).
printf %s "$user"
's stdout is a byte stream.
printf %s "$user" | openssl dgst -sha256 –binary
Will connect printf
's stdout with openssl
's stdin. openssl
's stdout is another byte stream.
Now, if you're inputing $user
from the user from a terminal, The user will enter it by pressing keys on his keyboard. The terminal will send corresponding characters (as written on the key label) encoded in its configured character set. Usually, that character set will be based on the character set in the current locale. You can find what that is with locale charmap
.
For instance, with a locale like fr_FR.iso885915@euro
, and an xterm
started in that locale, locale charmap
will return ISO-8859-15
. If the user enters stéphane
as the username, that é
will likely be encoded as the 0xe9
byte because that's how it's defined in the ISO-8859-15
character set.
If you want that é
to be encoded as UTF-8 before passing to openssl
, that's where you'd use iconv
to convert that 0xe9
byte to the corresponding encoding in UTF-8 (two bytes: 0xc3
0xa9
):
IFS= read -r user # read username from stdin as a sequence of bytes
# assumed to be encoded from characters as per the
# locale's encoding
printf %s "$user" |
iconv -t utf-8 | # convert from locale encoding to UTF-8
openssl dgst -sha256 –binary
In bash:
toBinary(){
local n bits sign=''
(($1<0)) && sign=-
for (( n=$sign$1 ; n>0 ; n >>= 1 )); do bits=$((n&1))$bits; done
printf "%s\n" "$sign${bits-0}"
}
Use:
$> toBinary 304
100110000
Or more POSIX_ly:
toBinaryPOSIX(){
n=$(($1))
bits=""
sign=""
if [ "$n" -lt 0 ]; then
sign=- n=$((-n))
fi
while [ "$n" -gt 0 ]; do
bits="$(( n&1 ))$bits";
: $(( n >>= 1 ))
done
printf "%s\n" "$sign${bits:-0}"
}
Use:
$> toBinaryPOSIX 304
100110000
If Value is hex:
$> toBinaryPOSIX 0x63
1100011
Best Answer
There's a
printf
tool that simulates the C function; normally it's at/usr/bin/printf
, but a lot of shells implement built-ins for it as well. You can use%02x
to get the hex representation of a character, but you need to make sure you pass a string that includes the character in single-quotes (Edit: It turns out just a single-quote at the beginning is sufficient):You can make a shell function for convenience: