494

I would like to write a bash script to decode a base64 string. For example I type decode QWxhZGRpbjpvcGVuIHNlc2FtZQ== and it prints Aladdin:open sesame and returns to the prompt.

So far I have tried a simple bash file containing python -m base64 -d $1 but this command expects a filename not a string. Is there another non-interactive command (not necessarily in a Python module) that I can run from the command line to achieve this, without having to install any extra packages? (Or if I do, something super-minimal.)

709

Just use the base64 program from the coreutils package:

echo QWxhZGRpbjpvcGVuIHNlc2FtZQ== | base64 --decode

Or, to include the newline character

echo `echo QWxhZGRpbjpvcGVuIHNlc2FtZQ== | base64 --decode`

output (includes newline):

Aladdin:open sesame
| improve this answer | |
  • 10
    Or: echo QWxhZGRpbjpvcGVuIHNlc2FtZQ== | base64 --decode && echo – Greg Chabala Sep 4 '14 at 16:08
  • 70
    Or: base64 -d <<< QWxhZGRpbjpvcGVuIHNlc2FtZQ== – jmk Jul 29 '15 at 11:23
  • 4
    echo QWxhZGRpbjpvcGVuIHNlc2FtZQ== | "C:\Program Files\Git\usr\bin\base64" --decode 2> nul > example.txt On Windows with git's base64. – Fire Sep 19 '16 at 18:03
  • 3
    @January It is not Just use, because many people know about the base64 program – but as one can't just insert a string as command line option, it is hard to get the syntax right for users who touch the CLI only once in a while. – feeela Nov 15 '16 at 14:04
  • 12
    On Mac, copy the the encoded string into clipboard and run pbpaste | base64 --decode. – Marián Černý Sep 21 '17 at 11:15
105

openssl can also encode and decode base64

$ openssl enc -base64 <<< 'Hello, World!'
SGVsbG8sIFdvcmxkIQo=
$ openssl enc -base64 -d <<< SGVsbG8sIFdvcmxkIQo=
Hello, World!

EDIT: An example where the base64 encoded string ends up on multiple lines:

$ openssl enc -base64 <<< 'And if the data is a bit longer, the base64 encoded data will span multiple lines.'
QW5kIGlmIHRoZSBkYXRhIGlzIGEgYml0IGxvbmdlciwgdGhlIGJhc2U2NCBlbmNv
ZGVkIGRhdGEgd2lsbCBzcGFuIG11bHRpcGxlIGxpbmVzLgo=
$ openssl enc -base64 -d << EOF
> QW5kIGlmIHRoZSBkYXRhIGlzIGEgYml0IGxvbmdlciwgdGhlIGJhc2U2NCBlbmNv
> ZGVkIGRhdGEgd2lsbCBzcGFuIG11bHRpcGxlIGxpbmVzLgo=
> EOF
And if the data is a bit longer, the base64 encoded data will span multiple lines.
| improve this answer | |
  • 9
    Thanks to Philippe's answer, you need to add -A for long base64 strings otherwise openssl will return nothing, see askubuntu.com/a/271676/305568 – morloch Oct 2 '14 at 6:02
  • @morloch or just avoid removing the newlines from the base64 encoded data, and it works as expected... – geirha Oct 2 '14 at 7:56
  • 1
    I would not consider coreutils an "additional" package containing programs like ls, mkdir, cp, mv, and chmod. I doubt you can do anything useful with your machine without it. – vidstige Jan 15 '15 at 20:14
  • @vidstige, that's true. I don't know why I was under the impression that base64 was not installed by default; that is totally not the case. – geirha Jan 16 '15 at 14:26
  • 1
    While this is the ubuntu stack exchange, using openssl has the advantage over standard base64 of working in Git Bash on Windows, at least the older 1.8.1 Git Bash version I have installed. – willkil Jun 16 '15 at 23:05
42

Here you go!

Add the following to the bottom of your ~/.bashrc file:

decode () {
  echo "$1" | base64 -d ; echo
}

Now, open a new Terminal and run the command.

decode QWxhZGRpbjpvcGVuIHNlc2FtZQ==

This will do exactly what you asked for in your question.

| improve this answer | |
20

With your original dependencies it is possible to do this with a minor modification to your original script:

echo $1 | python -m base64 -d

If you don't pass a file name, that python module reads from the standard input. To pipe the first parameter into it you can use echo $1 |.

| improve this answer | |
  • 1
    Also: python -m base32 filename – kenorb Nov 10 '12 at 22:57
  • 1
    this does not work :) but use .b32* methods – rzr Feb 16 '14 at 11:11
15

I did comment base64 command line in http://wiki.opensslfoundation.com/index.php?title=Command_Line_Utilities. So I issue a Warning when using openssl base64 decoding :

 openssl base64 -e <<< 'Welcome to openssl wiki'

 V2VsY29tZSB0byBvcGVuc3NsIHdpa2kK



openssl base64 -d <<< 'V2VsY29tZSB0byBvcGVuc3NsIHdpa2kK'

Welcome to openssl wiki

warning base64 line length is limited to 64 characters by default in openssl :

 openssl base64 -e <<< 'Welcome to openssl wiki with a very long line
 that splits...'

 V2VsY29tZSB0byBvcGVuc3NsIHdpa2kgd2l0aCBhIHZlcnkgbG9uZyBsaW5lIHRo
 YXQgc3BsaXRzLi4uCg==

openssl base64 -d <<< 'V2VsY29tZSB0byBvcGVuc3NsIHdpa2kgd2l0aCBhIHZlcnkgbG9uZyBsaW5lIHRoYXQgc3BsaXRzLi4uCg=='

=> NOTHING !

to be able to decode a base64 line without line feed that exceed 64 characters use -A option :

openssl base64 -d -A <<<
'V2VsY29tZSB0byBvcGVuc3NsIHdpa2kgd2l0aCBhIHZlcnkgbG9uZyBsaW5lIHRoYXQgc3BsaXRzLi4uCg=='

Welcome to openssl wiki with a very long line that splits...

This is anyway better to actualy split base64 result in 64 characters lines since -A option is BUGGY ( limit with long files ).

| improve this answer | |
4

Using perl

perl -MMIME::Base64 -ne 'printf "%s\n",decode_base64($_)' <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="

Or the same with python

python -m base64 -d <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
| improve this answer | |
3

Just to add another way to do it:

emacs -Q --batch  -eval '(princ (base64-encode-string (read-string ": ")))'
| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.