520

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.)

1
  • Nice question. And thanks for your hint, I now know the python -m base64 -h can become handy. – RayLuo Jan 27 at 0:34
747

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
7
  • 10
    Or: echo QWxhZGRpbjpvcGVuIHNlc2FtZQ== | base64 --decode && echo – Greg Chabala Sep 4 '14 at 16:08
  • 76
    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
108

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.
5
  • 10
    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
44

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.

0
21

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 |.

2
  • 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 ).

1
4

Using perl

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

Or the same with python

python -m base64 -d <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
3

Just to add another way to do it:

emacs -Q --batch  -eval '(princ (base64-encode-string (read-string ": ")))'
0

I had a few moments of hair-pulling on this one because the base64 Linux tool and also the openssl can decode, indeed. But I have this particular base64 encoded file that decodes to slightly wrong value. The few bytes do match, but then there is this presence of EF BF BD EF BF BD when I view in hexedit viewer. And then the next sequence of bytes match again when compared to the correctly decoded expected output. These weird sequence of bytes got inserted in the in-betweens, sometime as EF BF BD only.

To resolve the matter, I have to look how the Java sender encodes it and then I created a small java base64 decoder. And now I can decoded to the expected value.

Here is the small snippet that does it: https://gist.github.com/typelogic/0567cdab6c15487c31496cb90006ff52

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