base64 encode/decode multiple files
Tags: zsh, terminal, bash
Published: 2021-07-28 17:00:17

I'm actually working on a project that needs a lot of conversions between files and base64. At first, the easy way that I found to make this transformation was using the [Base64 Guru]( https://base64.guru/) page.

But the repetitive task of copying the long base64 text, pasting it on the web page, wait a loooooong time to make the (remote) conversion, and downloading the file was slowing the whole process.

I found a faster way to do it directly on my machine creating two bash files to make the encode and decode conversion even with multiple files inside the same folder. Now the whole process of conversion takes only 10% of the time compared to the web.

So, if you need to make a lot of operations converting multiples files inside a path to base64 or conversely, feel free to use this scripts.

I've tested it on Windows with WSL2, but I think It can work without a problem on macOS and Linux.

---

First of all we need to create a folder to save our helper functions. I used to name it `.helpers` inside home directory.

# Project

`take` command on zsh automatically creates folders and change the directories.

```
take .helpers/b64
```

Now we are going to make a script to encode a file to base64. Create a file called `file_to_b64` inside the `b64` folder and put this code.

```bash
#!/bin/bash

while getopts ":e:p:" opt; do
    case $opt in
        e) ext="${OPTARG}"
        ;;
        p) path="${OPTARG}"
        ;;
        \?) echo "Invalid option -${OPTARG}" >&2
        exit 1
        ;;
    esac
done

if [ -z ${ext} ]; then
    echo "ERROR: Extension is missing"
    exit 1
fi

if [ ! -z ${path} ]; then
    path="${path}/"
fi

for file in ${path}*.${ext}; do
    [ -e "${file}" ] || continue
    filename=${file%%.*}

    if [ -f "${filename}.b64" ]; then
        rm -r "${filename}.b64"
    fi
    base64 ${file}|tr -d '\n' > "${filename}.b64"

    echo "SUCCESS: '${filename}.b64' file was created"
done
```

Now we are going to make a script to decode from base64 to a file . Create a file called `b64_to_file` inside the `b64` folder and put this code.

```bash
#!/bin/bash

while getopts ":p:" opt; do
    case $opt in
        p) path="${OPTARG}"
        ;;
        \?) echo "Invalid option -${OPTARG}" >&2
        exit 1
        ;;
    esac
done

if [ ! -z ${path} ]; then
    path="${path}/"
fi

for file in ${path}*.b64; do
    [ -e "$file" ] || continue
    filename=${file%%.*}
    
    base64 --decode --ignore-garbage ${file} > "${filename}.tmp"
    ext=$(file -b --mime-type ${filename}.tmp | cut -d'/' -f2)

    if [ ! -z ${ext} ]; then
        if [ -f "${filename}.${ext}" ]; then
            rm -r "${filename}.${ext}"
        fi
        mv "${filename}.tmp" "${filename}.${ext}"

        echo "SUCCESS: '${filename}.${ext}' file was created"
    else
        rm -r "${filename}.tmp"
        echo "ERROR: '${filename}.b64' has no mime-type"
    fi
done
```

---

# Permissions

Add execution permissions to those files with:

```bash
chmod +x ~/.helpers/**/*
```

---

# Path

It's not good idea navigate to `.helpers/b64` folder each time we want to use those commands. 

In order to make it globally available need to add this `PATH` and alises to `.zshrc`.

```bash
export PATH="$HOME/.helpers/b64/:$PATH"
alias b2f="b64_to_file"
alias f2b="file_to_b64"
```

Once finish, reopen all terminals or update his source running source ~/.zshrc command and now you can use the new commands.

---

# Usage

It's recommended navigate to the path where the files are located, but also you can specify the path to apply the conversion. 

## To Encode

Put the files you want to encode to base64 inside a folder and run this command with the `-e` extension file name parameter.

```bash
file_to_b64 -e jpg #current path
file_to_b64 -e jpg -p foldername
# with alias
f2b -e jpg -p ~/dev/files
```

## To Decode

It will take all `*.b64` files and decode to files. No need to define the extension, it will search inside the mime file type.

```bash
b64_to_file #current path
b64_to_file -p foldername
# with alias
b2f -p ~/dev/files
``` 
---

# Bonus Track

Preview images inside vscode is an advantage while developing because you can see and manage the images directly on the code editor.

- [Image preview](https://marketplace.visualstudio.com/items?itemName=kisstkondoros.vscode-gutter-preview)
- [TIFF Preview](https://marketplace.visualstudio.com/items?itemName=analytic-signal.preview-tiff)

---

You can download or clone this code and other ZSH utilities from GitHub: [dot Files](https://github.com/deinsoftware/dot-files) repository.

---

**That’s All Folks!**
**Happy Coding** 🖖

[![beer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mkgsx4aw6qn9i9ax6as9.png)](https://github.com/sponsors/deinsoftware)