Is there a terminal command in macOS/OS X which will base64 encode a file or stdin?
19 Answers
openssl can do this for you, and it's all installed with OS X by default; no need to install darwinports.
$ openssl base64 -in <infile> -out <outfile>
Without the -in option reads from stdin
- 55,001
- 7,193
-
114Use
openssl base64 < path/to/file.png | tr -d '\n' | pbcopyorcat path/to/file.png | openssl base64 | tr -d '\n' | pbcopyto skip writing to a file and just copy the base64-encoded output to the clipboard without the line breaks. – Mathias Bynens Apr 12 '11 at 13:07 -
7
-
17In mac, To base64 encode a string:
openssl base64 -e <<< ramand to decode:openssl base64 -d <<< cmFtCg==– Ram Patra Nov 13 '14 at 10:52 -
is there an option to output the base64-encoded string in the terminal? – Zerium Apr 08 '15 at 00:19
-
1never mind, I found it:
openssl base64 < path/to/fileshould work fine. – Zerium Apr 08 '15 at 00:19 -
14@mathias if you want no newlines
openssl base64 [-e] -Adoes that. + @kenny on decode if input does not have newline every 76 chars at most, including the no-newlines case I just stated, you need-d -Aor you will get missing or corrupted data with no error message (although there is a pending bug report which may result in a fix to that). – dave_thompson_085 May 27 '15 at 14:54 -
2@Ram,
openssl base64 -e <<< ramactually encodes 4 bytes, including a trailing line feed; seehexdump <<< ram. – Arjan Jun 03 '15 at 20:39 -
-
1Taking @MathiasBynens even further:
pbpaste | openssl base64 -A | pbcopyto automagically transform what's on your clipboard into base64. (added -A) – evan.bovie Feb 01 '19 at 23:03
OpenSSL can be used more succinctly:
echo -n 'input' | openssl base64
echo -n -> must be used, or encoding will be done including new line character.
Or:
openssl base64 <ENTER> [type input] <CTRL+D>
- 55,001
- 2,299
-
20The "echo" solution adds a LF (line feed) char to the end of the input string, though. Better use: echo -n 'input' – SuperTempel Jul 17 '12 at 15:17
-
15
-
6Or just use
base64withoutopenssl. Either way, I need to press Ctrl+D twice. And beware, @Garret: in Bash, with or withoutopenssl,openssl base64 <<< superuserandopenssl base64 <<< "superuser"erroneously yieldc3VwZXJ1c2VyCg==, as the "here string" then still includes a line feed! (Apparently not only in Bash, but also in zsh, ksh and yash. Seehexdump <<< superuser. The Base64 result should bec3VwZXJ1c2Vy.) – Arjan Jun 03 '15 at 20:37 -
@Arjan I'd hesitate to use the word "erroneously" - as you pointed out, the here-string includes a line feed, but for good reason - http://unix.stackexchange.com/questions/20157/why-does-a-bash-here-string-add-a-trailing-newline-char .
echo -nis preferred if you don't need the newline. It's certainly something to be aware of. – Steve Folly Jun 05 '15 at 07:33 -
@Steve, indeed, it's not
openssl base64nor Bash that are to blame. But it surely is not the expected outcome when encoding the wordinput, so I wanted to ensure the "erroneously" is seen by future readers ;-) – Arjan Jun 05 '15 at 07:51 -
3
Try using:
base64 -i <in-file> -o <outfile>
It should be available by default on OS X.
- 25,417
- 1,129
-
2
-
3This is better for encoding for SVG because it creates one line. This is cleaner than the output from
openssl base64. Thanks! – Shanimal Apr 18 '19 at 01:35 -
I didn't want to use files so you can do
echo -n "something" | base64– Mike Harrison Feb 03 '22 at 22:51
On macOS I always use:
echo -n "STRING" | base64
-n is to avoid a new line character on the end of the line.
- 55,001
- 1,517
base64 command is available by default on my OS X 10.9.4.
You can use base64 <<< string and base64 -D <<< string to encode and decode a string in the terminal, or base64 -in file and base64 -D -in file to encode and decode a file.
- 759
-
Do you have an example? I get
Invalid characer in input streamwhen using<<<...I have tried with",'and nothing around the string. – Jonas Sep 20 '16 at 11:46 -
-
-
10Please note
base64 <<< catis equivalent toecho cat|base64, notecho -n cat|base64. Basically the automatic linefeed will be added to the base64 encoded string, and that might not be what you want. – Bill Apr 12 '20 at 03:29
Since Python is provided with OS X by default, you can use it as below:
$ echo FOO | python -m base64
Rk9PCg==
$ echo Rk9PCg== | python -m base64 -d
FOO
Or install coreutils via Brew (brew install coreutils) which will provide base64 command:
$ echo FOO | base64
Rk9PCg==
$ echo Rk9PCg== | base64 -d
FOO
- 25,417
You can also pipe it right to the clipboard (at least on mac):
openssl base64 -in [filename] | pbcopy
- 55,001
- 517
Python
Python3 comes preinstalled on all modern macs and linuces nowadays. The base64 module in the standard library exposes a cli interface (see python3 -m base64 -h)
Encode
# encode /etc/hosts to hosts.b64 in the current folder
# passing -e is optional since it's the default operation
python3 -m base64 -e < /etc/hosts > hosts.b64
encode a literal string to stdout (❗️appends a new line char)
python3 -m base64 <<< 'nobody expects the spanish inq..'
OUT: bm9ib2R5IGV4cGVjdHMgdGhlIHNwYW5pc2ggaW5xLi4K
Decode
# decode hosts.b64 to hosts.txt
python3 -m base64 -d < hosts.b64 > hosts.txt
The python code in case you need to script it from python:
Encode a file:
base64data = open('myfile.jpg','rb').read().encode('base64')
open('myfile.txt','w').write(base64data)
Encode a byte string without including the trailing new line:
import binascii
encoded = binascii.b2a_base64(b'nobody expects..', newline=False)
print(encoded)
# OUT: b'bm9ib2R5IGV4cGVjdHMuLg=='
alternative solution
import base64
encoded = base64.standard_b64encode(b'nobody expects..')
print(encoded)
OUT: b'bm9ib2R5IGV4cGVjdHMuLg=='
Decode a file:
data = open('myfile.b64').read().decode('base64')
open('myfile.jpg','wb').write(data)
OpenSSL
# encode to base64 (on OSX use `-output`)
openssl base64 -in myfile.jpg -output myfile.jpg.b64
encode to base64 (on Linux use -out)
openssl base64 -in myfile.jpg -out myfile.jpg.b64
decode from base64 (on OSX -output should be used)
openssl base64 -d -in myfile.jpg.b64 -output myfile.jpg
decode from base64 (on Linux -out should be used)
openssl base64 -d -in myfile.jpg.b64 -out myfile.jpg
Omitting the -out/-output... filename will print to stdout.
You can also pass the input data as a stream in a OS-agnostic way, e.g.
# encode /etc/hosts to hosts.b64
openssl base64 < /etc/hosts > hosts.b64
decode hosts64.b64 to hosts.txt
openssl base64 -d < hosts.b64 > hosts.txt
decode raw data to stdout (don't use with binary files)
openssl base64 -d < hosts.b64
Base64
Another out of the box utility commonly available on both mac and Lunux:
# encode to base64
base64 < myfile.jpg > myfile.jpg.b64
decode from base64 (OSX) (note the uppercase '-D', '-d' might also be accepted newer OS's)
base64 -D < myfile.jpg.b64 > myfile.jpg
decode from base64 (Linux) (note the lowercase 'd')
base64 -d < myfile.jpg.b64 > myfile.jpg
- 7,763
In terms of speed, I would use OpenSSL followed by Perl, followed by uuencode. In terms of portability, I would use uuencode followed by Perl followed by openssl (If you care about reusing the code on as many other UNIX like stock platforms as possible). Be careful though because not all UNIX variants support the -m switch (If I recall correctly, AIX does, HP/UX does, Solaris doesn't).
$ time perl -MMIME::Base64 -e 'undef $/;while(<>){print encode_base64($_);}' \
> out.jpg 1>filename.b64
real 0m0.025s
$ time uuencode -m -o filename.b64 out.jpg filename_when_uudecoded.txt
real 0m0.051s
$ time openssl base64 -in out.jpg -out filename.b64
real 0m0.017s
Use the -m switch to uuencode file_in.txt per base64 as specified by RFC1521 and write it to filename.b64 (with filename_when_uudecoded.txt as the default filename when decoded):
uuencode -m -o filename.b64 file_in.txt filename_when_uudecoded.txt
STDIN example:
cat file_in.txt | uuencode -m -o filename.b64 filename_when_uudecoded.txt
- 55,001
- 346
In addition to Steve Folly's answer, when encoding in stdin mode, to avoid passing extra newlines, press CTRL+D twice to end input without any additional newlines.
The output will show right after the same line.
For example:
$ openssl base64 <kbd>Enter</kbd>
input<kbd>CTRL</kbd>+<kbd>D</kbd><kbd>CTRL</kbd>+<kbd>D</kbd>aW5wdXQ=
Alternatively, you could use printf:
$ printf 'input' | openssl base64
aW5wdXQ=
- 55,001
- 141
uuencode -m [-o output_file] [file] name
Where name is the name to display in the encoded header.
Example:
cat docbook-xsl.css | uuencode -m docbook-xsl.css
or
uuencode -m -o docbook-xsl.css.b64 docbook-xsl.css docbook-xsl.css
- 24,424
- 31
For some reason, echo -n <data> | openssl base64 added a newline in the middle of my base64 data. I assume it was because my base64 data was really long.
Using echo -n <data> | base64 to encode and echo -n <base64-ed data> | base64 -D to decode worked fine.
- 1,290
-
nb: on my nix, i had to use -d
echo -n c29tZXVzZXI6c29tZXBhc3N3b3Jk | base64 -dsomeuser:somepassword
– mlo55 Apr 14 '16 at 00:07
There is Perl plus MIME::Base64:
perl -MMIME::Base64 -e 'undef $/;while(<>){print encode_base64($_);}'
This comes pre-installed. You can specify separate files on the command line (or supply the data on standard input); each file is separately encoded. You can also do:
perl -i.txt -MMIME::Base64 -e 'undef $/;while(<>){print encode_base64($_);}' file1
This backs up file1 to file1.txt, and writes the Base-64 encoded output over the original file.
- 5,043
Cross-platform solutions
We compiled a list of cross-platform shell commands to encode a file as base64. The following commands take an input file (named deploy.key in examples) and convert it to base64 without any newline wrapping. The base64 output is printed to the terminal via stdout.
# For systems with openssl
openssl base64 -A -in=deploy.key
For systems with Python (2 or 3) installed
python -c "import base64; print(base64.standard_b64encode(open('deploy.key', 'rb').read()).decode())"
For Windows or Linux systems that have the GNU coreutils base64 command
base64 --wrap=1000000 deploy.key
For macOS systems
base64 --break=1000000 deploy.key
To redirect the output to a file, append > base64-encoded.txt (using a file name of your choosing).
These commands were prototyped as part of this pull request where we wanted cross-platform shell commands to base64 encode an SSH private key to remove newlines.
- 55,001
There are many great answers already and mine does basically the same thing except the secret is never shown in the terminal.
I created these two aliases to encode a string from my clipboard and the encoded string is copied to my clipboard. The same applies to decoding:
alias decode='pbpaste | base64 --decode | pbcopy'
alias encode='pbpaste | base64 | pbcopy'
- 111
A simple NodeJS version:
node -e "process.stdout.write(new Buffer(process.argv[1]).toString('base64'))" "Hello world!"
- 127
-
I don't think this is a better answer as
openssl(and nowbase64) come with the OS. – Josh Mar 27 '15 at 15:01 -
At the risk of splitting hairs — and, I’m aware that this criticism applies to a couple of the other answers, as well — the question asked how to encode *a file* or *stdin*. If I’m not mistaken, your answer shows only how to encode a string. – G-Man Says 'Reinstate Monica' Mar 27 '15 at 19:00
If you are base64 encoding a font file, you can do this:
base64 my-webfont.ttf > my-webfont.b64.ttf.txt
I use this on a Mac (10.10) all the time.
Note: There will be no linebreaks.
- 119
recode should do the trick for you
recode ../b64 < file.txt > file.b64
recode is available for OS X via MacPorts.
- 55,001
- 63,745
-
1
-
-
1MacPorts does not come with any OS X distribution. There are plenty of other options that do. For instance just
base64command. – Jason S Sep 05 '16 at 06:05
On Mac, you can simply encode and decode the current clipboard contents to/from base64 with:
Encode to base64:
pbpaste | base64Decode from base64:
pbpaste | base64 --decode
- 55,001
- 191
base64 -dorbase64 -Ddepending on your operating system. OSX uses-D. – Chris Johnson Nov 30 '12 at 22:06opensslthe flag for decoding is-don OS X (10.10 Yosemite). – ᴠɪɴᴄᴇɴᴛ Jun 10 '15 at 12:11echo -n password | base64in your MacOS Terminal; andecho -n password | base64 -Dto decode. – Bugs Bunny May 30 '23 at 19:29