Hanatare's PaPa

Make life a little richer.

Virtual Space of Hanatare's PaPa

人生をほんの少しだけ充実させる

【エンコーディング】エンコーディング・暗号化・ハッシュ化の違い

今回は暗号化とエンコーディングの違いを整理したいと思います。エンジニアで仕事をしていると、暗号化・エンコーディング・ハッシュ化と似ているが、微妙に異なる処理があります。内容を理解していると全然違う意味ですが、曖昧な理解で使うと誤解を招いてしまうので、正しく理解するために整理したいと思います。主にエンコーディング中心の内容になっています。

記事のポイント
  • 暗号化とエンコーディングの違いを正しく理解する

エンコーディングとは

エンコーディングを理解するにあたって、符号化文字集合、文字コード、エンコーディングという言葉の違いを正しく理解する必要があります。それぞれ、文字を表現するために使用されますが、異なる意味を持ちます。

符号化文字集合とは

符号化文字集合は、ある言語や、文字の体系に属する文字の集合のことを指します。日本語で言うと、 JISX0201やJISX0208というJIS規格によって定義された扱える文字が存在します。 符号化文字集合にはいくつかの対応表が存在しています。以下に例を示しておきます。

  • JISX0201(日本語第1水準)
  • JISX0208(日本語第2水準)
  • ASCII
  • UNICODE

文字コードとは

文字コードと符号化文字集合は、とくに密接に関係しますが、異なる意味を持ちます。符号化文字集合は文字の集合体ですが、コンピューターでは文字を直接扱うことはできないため、数字にマッピングする必要があります。そのマッピングされた数字のことを文字コードと言います。たとえば、UNICODEの文字コードで規定された「あ」という文字は、「U+3042」(16進数)にマッピングしますが、その数値(1(「U+3042」)を文字コードと呼びます。 文字コードには、いくつかの種類が存在します。以下に例を示しておきます。

  • Shift_JIS
  • ASCII
  • UNICODE

エンコーディングとは

データをルールにしたがって、コンピューターが、理解できるデータに変換する行為のことを言います。 変換する行為のことを符号化とも呼びます。エンコーディングは文字コードで定義された数字を、コンピューターで扱える2進数のデータに変換する規則を指します。エンコーディング方式もいくつかの種類があります。以下に例を示します。

  • Shift_JIS
  • EUC-JP
  • UTF-8
  • UTF-16

エンコーディング(Encoding)とエンコード(Encode)の違い

エンコーディングは方式を指します。つまり、「UTF-8やShift_JIS」といったルールです。そしてエンコードは「UTF-8やShift_JISで変換する」という行為を表します。

符号化文字集合と文字コードとエンコーディングの違い

  • 符号化文字集合・・・ある特定の文字集合を表すための、符号化システム
  • 文字コード・・・特定の文字に対応する数値コード
  • エンコーディング・・・データを別の形式に変換するルール
  • エンコード・・・エンコーディングに基づいて、データを変換する行為

ここまで記載して「???」となっている箇所がある人もいると思います。エンコーディングのShift_JISと文字コードのShift_JIS、符号化文字集合のUnicodeやASCIIと文字コードのUnicode、ASCIIで被っています。この被りのせいで、私はなかなか、この3つの違いを、うまく理解できませんでした。 これらの言葉は、それぞれ2つの意味を表しています。

Unicode

Unicodeは、世界中の文字を扱えるようにしたISO(国際標準化機構)規格の文字集合のことです。 Unicodeで割り当てられた数値に対して、エンコーディングを行う際に、UTF-8やUTF-16、UTF-32という方式が存在しています。

UTF-8

・  Unicodeの符号を8ビット単位で表す

・ 1バイトから4バイトまでの可変長

・ ASCIIとの互換性有り

・  BOM(バイト・オーダー・マーク)不要

・ HTMLやXMLファイルのデフォルトエンコーディング

UTF-16

・ Unicodeの符号を16ビット単位で表す

・ 2バイトまたは4バイトの固定長

・ Javaの文字列表現など内部的な表現として使われる

・ 非ASCII互換

ASCII

ASCIIもUnicode同様に文字を表現するため符号化文字集合を表します。Unicodeと異なるのは、ASCIIはアルファベットの大文字、小文字、数字、一部の記号など128種類の文字を定義しています。

そして、その文字に対応した数値も合わせて規定しており、それが文字コードのASCIIとなります。

JISX0201やJISX0208

JISX0201やJISX0208というはJISが定義している、日本語の定義になります。コンピューターで日本語を扱う際に注意すべきことは、旧字体をどのように扱うかです。それぞれの規格でどこまでの範囲の漢字が扱えるのかは、要件定義や設計の際にはしっかりと意識したい部分です。

SHIFT_JISは、符号化文字集合で定義されたJISX0201やJISX0208の文字に対応した数値を持つ文字コードです。そして、割り当てられた数値をエンコーディングする際にも、SHIFT_JISというエンコーディング方式を用いてバイト列の変換ができます。主に日本語で広く扱われていますが、日本国内の利用が一般的なため、国際化に向けての問題点を指摘されています。

暗号化とは

機密性の高いデータをやり取りする際に、第三者にそのデータの中身を理解させないようにするための方法です。暗号化は、あらかじめ取り決めたルールに基づいて、データを、第三者が見てもわからない形に置きかえます。置きかえられたデータは、事前に決めたルールに従い、元のデータに戻すことで、内容の確認ができます。つまり、暗号化は、元に戻すことが前提に、他者にデータを読み取られないようにするための方法です。

ハッシュ化とは

ハッシュ化は、データを、固定長のハッシュ値に変換することを言います。ハッシュ値は、同じ入力データに対しては常に同じ値を返します。ただし、不可逆性を持ち、変換したデータを元にもどすことを前提にしていません。ハッシュ化、主に、Webサイトのパスワードの保存などで利用されます。入力されたパスワードをハッシュ化し、元の値とは異なる値にして、DBに保存します。ログイン時は、入力値をハッシュ化し、DBに保存したハッシュ化されたデータと照合します。 DBに保存されたパスワードが、何らかの理由で外部に漏れても、値を元の値に戻すことはできないため、被害を抑えることができます。

エンコーディング・暗号化・ハッシュ化の違い

エンコーディングはデータをコンピューターが扱えるように、変換するプロセスのことを指します。その際、扱える文字として符号化文字集合を使い、エンコーディングする際に、その文字とマッピングした数値として文字コードを使うと言うことになります。

暗号化はエンコーディングとは概念が異なり、変換する行為では同じですが、変換後と変換前で、データが同等であるかどうかと言う点で異なります。たとえば、エンコーディングでは「あ」という文字を数字に置き換えたり、2進数のバイト長に置き換えますが、どれも「あ」を意味します。

しかし、暗号化では「あ」と言う文字を「c4あdsふぁ」のような意味のない文字列に置き換えます。これは、データの機密性を守るために行う行為です。この変換前後で同等の意味を表すかという点で、暗号化とエンコーディングは異なります。

そしてハッシュ化は、暗号化とエンコーディングの違いに加えて、可逆性があるかどうか点で異なります。ハッシュ化、ハッシュ化した後のデータを戻すことを前提にしません。そのため不可逆なデータになると言う点で、エンコーディングや暗号化とはまた異なる概念を持ちます。

補足:Base64のエンコーディングとは

最後のおまけです。Base64でエンコーディングするという行為も、システム開発ではよく行います。バイナリデータ(画像や音声ファイルなど)を扱う際に、テキスト形式のデータに変換し、扱いやすくするために、使用します。Base64によってエンコードされたデータは、その方式で変換されていることが分かれば、誰でも元に戻すことができるため、こちらも暗号化とは異なる概念での利用になります。 「Base64で暗号化」という方が、私の現場ではたまにいますが、私は暗号化でないと考えています。

まとめ

今回はエンコーディング・暗号化・ハッシュ化の違いについて整理をしました。主にエンコーディングの部分が中心の議題になってしまいましたが、この辺の違いを正確に理解して、今後の要件定義・設計開発に活かしていきたいと思います。この記事が、読んでいただいた方の参考になれば、幸いです。