2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ハッシュ値を圧縮すればもっと短くできる?→長くなった

Posted at

時間がない方に向けて結論

ハッシュ文字列をzip圧縮すると、長くなります。
SHA256の場合:元256bit=64文字=32byte → 137byte(428%増)
SHA3_512の場合:元512bit=128文字=64byte → 169byte(264%増)

当たり前だろという声も聞こえる気がします。
恥を忍んでソースはこちら
https://github.com/yo16/compress_str

はじめに思ったこと

ハッシュ化して256bitなり512bitなりになった後の16進数の文字列を見ると、異常に長く感じますよね?長いですわ。例えばSHA256でも661b976821ad4a7545054a2e45367e3af53522477d39b28fdca26b36fed95f8b1a2005e3188b682a74f9e772aa3cb7201fcb6d01ce6cb2cdf720690fd26d5bb1eになって64文字。512だと倍。これをDBへ格納して、なんなら表示したりとか気が知れない。

だけどそもそも16進数、つまり読み直せば2進数、バイナリですよね。上のも、011110000101001010111000010101011....(さすがに略.16進数の4倍みたいに0/1の値。こうやって表現すると、これってコンピューターの中のバイナリファイルだなーと思いました。

そしたらそのバイナリファイルを圧縮すれば小さくなるんだから、圧縮結果をもう一度2進数にして、16進数にすれば、短い文字列ができるんじゃないか・・・?

実験

1. 文字列をハッシュ化する関数

記事の本筋ではないので超絶割愛。知りたければGitHubのソースを見てください。

hashing.py
# キモのところ
import hashlib
h = hashlib.sha256(s).hexdigest()

2. zip圧縮

ハッシュ化した文字列をバイナリ化して、zip化して、文字列化(16進数)する。
難しいことはないのだけれど、普段、バイナリの操作はあまりやらないので試行錯誤。

compress_str.py
def do_compress(str_hex:str)->str:
    """文字列の16進数をバイナリ値にそのまま変換し、zip圧縮して返す

    Args:
        str_hex (str): 16進数の文字列(先頭にbはない)

    Returns:
        str: zip圧縮したバイナリ値を16進数にした文字列
    """
    # 16進数文字列をそのままバイナリ化
    b = bytes.fromhex(str_hex)
    
    # バイナリをzip化
    zip_stream = io.BytesIO()
    with zipfile.ZipFile(zip_stream, 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
        new_zip.writestr('_', b)
    
    # zipしたバイナリ値をそのまま取得
    h = zip_stream.getvalue()

    # 16進数にして返す
    return h.hex()

3. 評価

実行するところとその結果。

compress_str.pyのメイン
test_str = 'test123'
#ret = do_hashing(test_str, ret_type='Hex', hash_method='SHA256')
ret = do_hashing(test_str, ret_type='Hex', hash_method='SHA3_512')
print(ret)
print(f'{len(ret)/2} bytes')        # 16進数1文字=4bit=0.5byte
# >>> 64.0 bytes

ret2 = do_compress(ret)
print(ret2)
print(f'{len(ret2)/2} bytes')
# >>> 169.0 bytes

最初に書いた通り、

  • SHA256の場合
    • 元256bit = 64文字 = 32byte
    • → Zip → 137byte(428%増)
  • SHA3_512の場合
    • 元512bit = 128文字 = 64byte
    • → Zip → 169byte(264%増)

ZIP圧縮方法変更してもっと圧縮するとかは、もうそういうレベルではないのでやってません。

あとがき

残念でしたが、思いついたことがダメだとすぐ判明してスッキリしました。コーディングできる人でよかった。(間違ってなければ)

2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?