Pythonで文字列などをハッシュ化する | パスワード管理に便利。

Python

Pythonで文字列などをハッシュ化するには?

Pythonで文字列などをハッシュ化して処理したい場合があります。

例えば以下シチュエーションで利用が可能でプログラムの安全性、整合性を大きく向上させることができます。

利用シチュエーション

データの安全性を保つ
パスワードや個人情報などの機密情報をハッシュ化して保存することで、万が一データベースが不正にアクセスされても、元の情報が直接見られる危険が減ります。ハッシュ化すると、元のデータから変換された文字列だけが保存されるので、仮に情報が漏れても安全性が向上します。

データの一意性を確保する
ハッシュ関数は特定の入力に対して一意な出力(ハッシュ値)を生成します。これにより、異なるデータが同じハッシュ値になる確率が非常に低くなり、データの識別が簡単になります。たとえば、ファイルが同じかどうかを判定する際に、ハッシュ化した値を比較することで、内容の一致を効率的に確認できます。

例えば、原稿用紙100枚の文書で変更点があった場合、変更前をA変更後をBとしてハッシュ化すると異なる値のハッシュ値が取得できないよう合致調査が可能です。

データ検証が簡単
大量のデータを保存する場合でも、ハッシュ値を使えば内容の整合性を素早く確認できます。たとえば、ダウンロードしたファイルが改ざんされていないかチェックしたいとき、元のハッシュ値とダウンロードしたファイルのハッシュ値を比較するだけで、データの正確さがわかります。

Pythonで文字列などをハッシュ化するサンプルコード

サンプルコードを紹介します。

import hashlib

def get_hash_string(input_str):
    """
    与えられた文字列をSHA-256でハッシュ化する関数。

    Parameters:
    input_str (str): ハッシュ化する文字列。例えば、'abcde123'。

    Returns:
    str: ハッシュ化された文字列(16進数表記)。
    """
    # SHA-256でハッシュ化する
    sha_hash = hashlib.sha256(input_str.encode('utf-8')).hexdigest()
    
    # SHA-512でハッシュ化する
    #sha_hash = hashlib.sha512(input_str.encode('utf-8')).hexdigest()

    return sha_hash



# テスト実行
if __name__ == "__main__":

    original_str = "abcde123"
    hashed_str = get_hash_string(original_str)

    # ハッシュ値の取得
    print(f"Original String: {original_str}")
    print(f"Hashed String: {hashed_str}")

実行結果

Original String: abcde123
Hashed String: 3332e5eea07ab9d93cd59e3748b9746f66c8abc3a7a126a5c1965ff8525e00ba

この例では、abcde123の文字列が3332e5eea07ab9d93cd59e3748b9746f66c8abc3a7a126a5c1965ff8525e00ba

となったことがわかります。

abcde123がパスワードだったとしたら

もしabcde123がパスワードだとしてデータベースに保存されていた場合、データベース管理者であればパスワードが見えてしまうことになりセキュリティが向上しません。そのためハッシュ値をデータベースに保存することでパスワードを隠蔽することが可能となります。

実際に比較してみましょう。
テスト実行部分を以下のように変更します。

# テスト実行
if __name__ == "__main__":

    original_str = "abcde123"
    hashed_str = get_hash_string(original_str)

    # ハッシュ値の取得
    print(f"Original String: {original_str}")
    print(f"Hashed String: {hashed_str}")
    
    change_str = "abcde124"
    hashed_str = get_hash_string(change_str)
    print(f"change_str: {change_str}")
    print(f"Hashed String: {hashed_str}")

original_str = "abcde123"
change_str = "abcde124"

と変更すると以下のようにハッシュ値が変わります。

Original String: abcde123
Hashed String: 3332e5eea07ab9d93cd59e3748b9746f66c8abc3a7a126a5c1965ff8525e00ba
change_str: abcde124
Hashed String: 9ac5b1ac2fe46a8a2605c8b7d22d7b2aa6b7d422909f1461dfa3793722dce5a0

ハッシュ値は不可逆ですのでabcde123には戻すことができません
したがって、ハッシュ値を比較することにより入力されたパスワードが正しいかどうかがわかることになります。

他にも

原稿用紙100枚分の文書(40,000文字)をハッシュ化するというのも、基本的には同じ考え方です。大量の文字からなる文書であっても、ハッシュ化すると、わずか数十文字のハッシュ値になります。たとえば、SHA-256を使えばどんなに長いテキストでも「64文字のハッシュ値」に変換されます。

# テスト実行
if __name__ == "__main__":

    original_str = "吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。"
    hashed_str = get_hash_string(original_str)

    # ハッシュ値の取得
    print(f"Original String: {original_str}")
    print(f"Hashed String: {hashed_str}")
    

スクロールして読みにくいと思うので文字列は以下を設定しています。

original_str = "吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。"

実行すると以下のようになります。

Original String: 吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは
時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。
Hashed String: 7f804adab3bd42293e1f78ef5a3828a314f43bfe8d1057b0c001ff71e322fdfa

ハッシュ化すると短くなります。
また1文字でも値が変わるとハッシュ値も変わるので、変更管理が可能となります。

テスト実行と実行結果は以下のようになります。

# テスト実行
if __name__ == "__main__":

    original_str = "吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。"
    hashed_str = get_hash_string(original_str)

    # ハッシュ値の取得
    print(f"Original String: {original_str}")
    print(f"Hashed String: {hashed_str}")

    
    change_str = "あ吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。"
    hashed_str = get_hash_string(change_str)
    
    print(f"change_str: {change_str}")
    print(f"Hashed String: {hashed_str}")
    
Original String: 吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは
時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。
Hashed String: 7f804adab3bd42293e1f78ef5a3828a314f43bfe8d1057b0c001ff71e322fdfa
change_str: あ吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。
Hashed String: b72e3a6c01995874e59ac3258244d48ec8bc2423364e4fa022995651f96879cf

吾輩は猫である。の前に「あ」を入れているだけでハッシュ値が変わっていることがわかります。

最後に

以上がPythonでハッシュ値を取得する方法です。

パスワード管理は特に利用度が高いと思いますので試してみてはいかがでしょうか。

コメント

タイトルとURLをコピーしました