basencコマンド: base64urlのencode/decodeが可能なツール

# 1. はじめに

base64のためのコマンドはあるのに、base64urlのためのコマンドがなくて、みんな頑張ってシェルで変換していたりpythonとかでコードを書いたりしているなー、標準ツールで対応されないのかなーって思ってたら、coreutilsの中に含まれているbasencというコマンドで実現できるということが分かった。

# 2. basencコマンドはどのパッケージに含まれているのか？

basencコマンドはcoreutilsに含まれているようだ。しかし、coreutilsはLinuxの基本的なコマンド(lsとかcpとか）を提供するツール群なので、これを勝手にアップデートするとシステムが壊しかねないリスクもありそうである。対応するバージョンがデフォルトで導入されているOSを選択した方がよさそうだ。

```
# rpm -qf '/usr/bin/ls'
coreutils-8.22-24.el7_9.2.x86_64

# rpm -qf '/usr/bin/cp'
coreutils-8.22-24.el7_9.2.x86_64
```

以下によると、basencコマンドが含まれているcoreutilsのバージョンはcoreutils-8.31以降のようだ。


https://lists.gnu.org/archive/html/info-gnu/2019-03/msg00003.html

>** New commands
>
>  basenc is added to complement existing base64,base32 commands,
  and encodes and decodes printable text using various common encodings:
  base64,base64url,base32,base32hex,base16,base2,z85.

# 3. coreutils-8.31以降が含まれるOSは？

[ここ](https://rpmfind.net/linux/rpm2html/search.php?query=coreutils)で探してみると、

- CentOS 7: coreutils-8.22
- CentOS 8-stream: coreutils-8.30
- CentOS 9-stream: coreutils-8.32

という感じのようだ。

# 4. CentOS 9-streamでの環境確認

IBM CloudではCentOS 9-streamが選択できるので、プロビジョニングしてみた。

```txt:環境確認
# cat /etc/redhat-release
CentOS Stream release 9

# uname -a
Linux syasuda-centos9 5.14.0-252.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Feb 1 13:25:18 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

# rpm -qa|grep coreutils
coreutils-common-8.32-34.el9.x86_64
coreutils-8.32-34.el9.x86_64
policycoreutils-3.5-0.rc2.1.el9.x86_64
python3-policycoreutils-3.5-0.rc2.1.el9.noarch

# which basenc
/usr/bin/basenc

# rpm -qfi '/usr/bin/basenc'
Name        : coreutils
Version     : 8.32
Release     : 34.el9
Architecture: x86_64
Install Date: Tue 14 Feb 2023 02:00:43 PM EST
Group       : Unspecified
Size        : 5966370
License     : GPLv3+
Signature   : RSA/SHA256, Thu 19 Jan 2023 05:39:23 AM EST, Key ID 05b555b38483c65d
Source RPM  : coreutils-8.32-34.el9.src.rpm
Build Date  : Fri 06 Jan 2023 06:40:51 AM EST
Build Host  : x86-04.stream.rdu2.redhat.com
Packager    : builder@centos.org
Vendor      : CentOS
URL         : https://www.gnu.org/software/coreutils/
Summary     : A set of basic GNU tools commonly used in shell scripts
Description :
These are the GNU core utilities.  This package is the combination of
the old GNU fileutils, sh-utils, and textutils packages.

[root@syasuda-centos9 ~]# basenc --help
Usage: basenc [OPTION]... [FILE]
basenc encode or decode FILE, or standard input, to standard output.

With no FILE, or when FILE is -, read standard input.

Mandatory arguments to long options are mandatory for short options too.
      --base64          same as 'base64' program (RFC4648 section 4)
      --base64url       file- and url-safe base64 (RFC4648 section 5)
      --base32          same as 'base32' program (RFC4648 section 6)
      --base32hex       extended hex alphabet base32 (RFC4648 section 7)
      --base16          hex encoding (RFC4648 section 8)
      --base2msbf       bit string with most significant bit (msb) first
      --base2lsbf       bit string with least significant bit (lsb) first
  -d, --decode          decode data
  -i, --ignore-garbage  when decoding, ignore non-alphabet characters
  -w, --wrap=COLS       wrap encoded lines after COLS character (default 76).
                          Use 0 to disable line wrapping

      --z85             ascii85-like encoding (ZeroMQ spec:32/Z85);
                        when encoding, input length must be a multiple of 4;
                        when decoding, input length must be a multiple of 5
      --help     display this help and exit
      --version  output version information and exit

When decoding, the input may contain newlines in addition to the bytes of
the formal alphabet.  Use --ignore-garbage to attempt to recover
from any other non-alphabet bytes in the encoded stream.

GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
Full documentation <https://www.gnu.org/software/coreutils/basenc>
or available locally via: info '(coreutils) basenc invocation'
```

# 5. 実行例

```txt:base64urlエンコード
# echo '{"sub":"1234567890","name":"John Doe","iat":1516239022}' | basenc --base64url
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQo=
```
```txt:base64urlデコード
# echo eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQo= | basenc -d --base64url
{"sub":"1234567890","name":"John Doe","iat":1516239022}
```