Python3 のハッシュ関数のアルゴリズム一覧の確認方法（hashlib モジュール）


> **Python3 のハッシュ関数で標準サポートされているアルゴリズムを知りたい**。

しかし、[「python3 hashlib アルゴリズム一覧」でググって](https://www.google.co.jp/search?q=python3+hashlib+%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E4%B8%80%E8%A6%A7)も、[Qiita 記事に絞って](https://www.google.co.jp/search?q=site:qiita.com+python3+hashlib+%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E4%B8%80%E8%A6%A7)も、ドンピシャで出てこなかったため未来の自分のググラビリティとして。

## TL; DR <sub><sup><sub><sup>（今北産業）</sup></sub></sup></sub>

1. <code>[hashlib](https://docs.python.org/ja/3.6/library/hashlib.html)</code> モジュールの、以下の<code>[セット（set）](https://docs.python.org/ja/3.6/library/stdtypes.html#set-types-set-frozenset)</code>で確認できます。
2. `algorithms_guaranteed`： 「標準サポート」のハッシュ・アルゴリズム・セット
3. `algorithms_available`： 「利用可能」なハッシュ・アルゴリズム・セット

```python:確認例
$ python3
Python 3.6.0 (default, Jun 18 2018, 13:35:26) 
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.10.25.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import hashlib
>>> print(sorted(hashlib.algorithms_guaranteed))
['blake2b', 'blake2s', 'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 
'sha3_384', 'sha3_512', 'sha512', 'shake_128', 'shake_256']
>>> 
>>> print(sorted(hashlib.algorithms_available))
['DSA', 'DSA-SHA', 'MD4', 'MD5', 'MDC2', 'RIPEMD160', 'SHA', 'SHA1', 'SHA224', 'SHA256', 
'SHA384', 'SHA512', 'blake2b', 'blake2s', 'dsaEncryption', 'dsaWithSHA', 'ecdsa-with-SHA1', 
'md4', 'md5', 'mdc2', 'ripemd160', 'sha', 'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224', 
'sha3_256', 'sha3_384', 'sha3_512', 'sha512', 'shake_128', 'shake_256', 'whirlpool']
>>> 
```

- [オンラインで確認する](https://paiza.io/projects/xG1TsN4OnNvbh9rsa_i_hA) @ paiza.IO

:::note info
- 同じ Python3 でもサブ・バージョンによって内容は異なります。また環境（インストール済みのモジュールなど）によっても内容は異なります。
- ほとんどの Python3 のバージョンで共通なのは以下
    - `md5`,`sha1`,`sha224`, `sha256`, `sha384`, `sha512`
- セキュリティアップデート済みの場合は、大抵以下のものが使える
    - `blake2bP`, `blake2s`, `md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha3_224`, `sha3_256`,
`sha3_384`, `sha3_512`, `sha512`, `shake_128`, `shake_256`
- 他のプログラム言語と互換性の高いものは以下
    - `md5`, `sha1`
    - `sha2` 系： `sha224`, `sha256`, `sha384`, `sha512`
    - `sha3` 系： `sha3_224`, `sha3_256`, `sha3_384`, `sha3_512` <font color=red>オススメ</font>
    - 可変長系： `shake_128`, `shake_256`
:::

## TS; DR <sub><sup><sub><sup>（OS 別のデフォルトで使えるハッシュ・アルゴリズムを調べたコマケーこと）</sup></sub></sup></sub>

- Python3 マニュアルの記述箇所
    - [hashlib.algorithms_guaranteed](https://docs.python.jp/3/library/hashlib.html#hashlib.algorithms_guaranteed) | hashlib.py | Python v3 @ Python 公式ドキュメント

- CPython のソースコード内定義箇所
    - ["hashlib.py" 58-68 行目](https://github.com/python/cpython/blob/3.6/Lib/hashlib.py#L58-L68) | Python v3.6 @ Python 公式リポジトリ @ GitHub

### Python3 で利用可能なハッシュ関数のアルゴリズムの調べ方

以下のスクリプトを各々の OS に設置して調べました。なお、OS は測定時の全ての Update が適用済みの状態です。（`apt update` など）

```python:show_algos.py
import hashlib

print("# 保証されたアルゴリズム一覧")
print(sorted(hashlib.algorithms_guaranteed))

print("# 利用可能なアルゴリズム一覧")
print(sorted(hashlib.algorithms_available))
```

以下を見るとわかるように、「保証されたアルゴリズム」（`algorithms_guaranteed`）と言っても、同じ Python3 でもマイナー・バージョンや環境によって**標準で利用可能なアルゴリズムは異なる**ので注意が必要です。（下記は、見やすいように改行を入れています）

#### macOS HighSierra (OSX 10.13)

```shell-session:macOS（HighSierra）での実行結果
$ date
2018年 11月 17日 土曜日 15:49:54 JST

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.13.6
BuildVersion:	17G3025

$ python3 -V
Python 3.6.0

$ python3 show_algos.py
# 保証されたアルゴリズム一覧
['blake2b', 'blake2s', 'md5', 'sha1', 'sha224', 'sha256', 'sha384',
 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512',
 'shake_128', 'shake_256']

# 利用可能なアルゴリズム一覧
['DSA', 'DSA-SHA', 'MD4', 'MD5', 'MDC2', 'RIPEMD160', 'SHA', 'SHA1',
 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'blake2b', 'blake2s',
 'dsaEncryption', 'dsaWithSHA', 'ecdsa-with-SHA1', 'md4', 'md5',
 'mdc2', 'ripemd160', 'sha', 'sha1', 'sha224', 'sha256', 'sha384',
 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512',
 'shake_128', 'shake_256', 'whirlpool']
```

#### macOS Catalina (OSX 10.15)

```shell-session:macOSでの実行結果
$ date
2021年 5月18日 火曜日 21時48分48秒 JST

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.7
BuildVersion:	19H1030

$ python3 -V
Python 3.9.4

$ python3 show_algos.py
# 保証されたアルゴリズム一覧
['blake2b', 'blake2s', 'md5', 'sha1', 'sha224', 'sha256', 'sha384',
 'sha3_224', 'sha3_256',
 'sha3_384', 'sha3_512', 'sha512', 'shake_128', 'shake_256']
# 利用可能なアルゴリズム一覧
['blake2b', 'blake2s', 'md4', 'md5', 'md5-sha1', 'mdc2',
 'ripemd160', 'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224',
 'sha3_256', 'sha3_384', 'sha3_512', 'sha512', 'sha512_224',
 'sha512_256', 'shake_128', 'shake_256', 'sm3', 'whirlpool']
```

#### Raspbian (Debian 8, Jessie)

```shell-session:Rarpbianでの実行結果
$ cat /etc/os-release | head -1
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"

$ python3 -V
Python 3.4.2

$ python3 show_algos.py
# 保証されたアルゴリズム一覧
['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']

# 利用可能なアルゴリズム一覧
['DSA', 'DSA-SHA', 'MD4', 'MD5', 'RIPEMD160', 'SHA', 'SHA1',
 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'dsaEncryption',
 'dsaWithSHA', 'ecdsa-with-SHA1', 'md4', 'md5', 'ripemd160', 
 'sha', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
 'whirlpool']
```

#### RaspberryPi OS (Debian 10, Buster)

```shell-session:
$ cat /etc/os-release | grep "PRETTY_NAME"
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"

$ python3 -V
Python 3.7.3

$ python3 show_algos.py
# 保証されたアルゴリズム一覧
['blake2b', 'blake2s', 'md5', 'sha1', 'sha224', 'sha256', 'sha384',
 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512',
 'shake_128', 'shake_256']
# 利用可能なアルゴリズム一覧
['blake2b', 'blake2b512', 'blake2s', 'blake2s256', 'md4', 'md5',
 'md5-sha1', 'ripemd160', 'sha1', 'sha224', 'sha256', 'sha3-224',
 'sha3-256', 'sha3-384', 'sha3-512', 'sha384', 'sha3_224',
 'sha3_256', 'sha3_384', 'sha3_512', 'sha512', 'sha512-224',
 'sha512-256', 'shake128', 'shake256', 'shake_128', 'shake_256',
 'sm3', 'whirlpool']
```

#### CentOS 7.5

```shell-session:CentOSでの実行結果
$ cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core) 

$ python3.6 -V
Python 3.6.5

$ python3.6 show_algos.py
# 保証されたアルゴリズム一覧
['blake2b', 'blake2s', 'md5', 'sha1', 'sha224', 'sha256', 'sha384',
 'sha3_224', 'sha3_256','sha3_384', 'sha3_512', 'sha512',
 'shake_128', 'shake_256']

# 利用可能なアルゴリズム一覧
['DSA', 'DSA-SHA', 'MD4', 'MD5', 'RIPEMD160', 'SHA', 'SHA1',
 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'blake2b', 'blake2s',
 'dsaEncryption', 'dsaWithSHA', 'ecdsa-with-SHA1', 'md4', 'md5',
 'ripemd160', 'sha', 'sha1', 'sha224', 'sha256', 'sha384',
 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512',
 'shake_128', 'shake_256', 'whirlpool']
```

```shell-session:Ubuntuでの実行結果
$ cat /etc/os-release | grep "PRETTY_NAME"
PRETTY_NAME="Ubuntu 18.04.1 LTS"

$ python3 -V
Python 3.6.6

$ python3 show_algos.py
# Supported Algorithms Guaranteed
['blake2b', 'blake2s', 'md5', 'sha1', 'sha224', 'sha256', 'sha384',
 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512',
 'shake_128', 'shake_256']

# Supported Algorithms Available
['BLAKE2b512', 'BLAKE2s256', 'MD4', 'MD5', 'MD5-SHA1', 'RIPEMD160',
 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'blake2b',
 'blake2b512', 'blake2s', 'blake2s256', 'md4', 'md5', 'md5-sha1',
 'ripemd160', 'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224',
 'sha3_256', 'sha3_384', 'sha3_512', 'sha512', 'shake_128',
 'shake_256', 'whirlpool']
```

- [オンラインで動作確認する](https://paiza.io/projects/xG1TsN4OnNvbh9rsa_i_hA) @ paiza.IO

ついでに Docker の Alpine Linux 

```shell-session:Docker(python:alpine)での実行結果
$ docker run --rm -it python:alpine /bin/sh

/ # cat /etc/os-release | grep "PRETTY_NAME"
PRETTY_NAME="Alpine Linux v3.13"

/ # python3 -V
Python 3.9.5

/ # vi show_algos.py
...(ソースをコピペ) ..

/ # python3 show_algos.py
# 保証されたアルゴリズム一覧
['blake2b', 'blake2s', 'md5', 'sha1', 'sha224', 'sha256', 'sha384',
 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512',
 'shake_128', 'shake_256']
# 利用可能なアルゴリズム一覧
['blake2b', 'blake2s', 'md4', 'md5', 'md5-sha1', 'ripemd160',
 'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256',
 'sha3_384', 'sha3_512', 'sha512', 'sha512_224', 'sha512_256',
 'shake_128', 'shake_256', 'sm3', 'whirlpool']

```

### 所感

以前「[hash アルゴリズムとハッシュ値の長さ一覧](https://qiita.com/KEINOS/items/c92268386d265042ea16)」をまとめたのですが、それらの一覧は PHP7 でサポートされているアルゴリズムであったため、**他のプログラム言語のハッシュ関数と共通のアルゴリズムを知りたい**と思いました。

そこで、まずは最近勉強している Python3 のハッシュ関数用の `hashlib` モジュールから調べてみました。

## 参考文献

- 「[`hashlib` モジュールのソースコード](https://github.com/python/cpython/blob/3.6/Lib/hashlib.py)」| Python3.6 @ Python 公式リポジトリ @ GitHub
- 「[`hashlib` --- セキュアハッシュおよびメッセージダイジェスト](https://docs.python.org/ja/3.6/library/hashlib.html)」| Python3.6 @ Python 公式ドキュメント