khurata’s blog

khurata’s blog

コンピュータの中での「表現」~文字・画像・音声・動画~

(もともと「Yahoo!知恵袋」の「知恵ノート」だったものを転載しています)
(最終更新日時:2015/1/12)投稿日:2012/6/8

はじめに

 コンピュータは、2進数しか処理出来ない、0と1だけを処理する……何十年も昔から、言われ続けてきた事です。 言葉だけなら、多くの方が御存知でありましょう。
 しかし、現在我々が実際に使っているコンピュータを見れば、0と1以外の数値、何万種類もある漢字、フルカラーの画像、音楽、動画……これらが、一体どうして「0と1だけ」なのか、不思議に思われた方もいらっしゃるのではないでしょうか。
(もちろん、「そんな基本的な事は全て分かっている」という方も、多いことでしょう)

 本ノートでは、その辺りについて、基本的なところを説明してみようと思います。
 これは、コンピュータに関する知識の中で、とても重要なのですが、実はそんなに難しい話ではありません。 ゆっくり読めば、必ず理解出来るものと思います。

 

なぜ2進数か

 現代使われているほとんど全てのコンピュータは、2進数(「0」と「1」の数字だけから成る数値)を処理する機械です。 2進数の1桁は0か1かしか扱えませんが、2桁なら00、01、10、11の4種類の値が扱えます(これは10進数で言えば0、1、2、3に該当します)。 桁数を増やせば、いくらでも大きな数値が扱えます。 10桁の2進数なら10進数の0から1023までを、20桁の2進数なら10進数の0から1048575までを扱えます。

 我々が普段使い慣れている10進数ではなく、なぜ2進数を使うのかと言うと、色々理由はありますが、最大の理由は、計算回路を作りやすいからです。

 2進数1桁どうしの加算ルールは、次の4通りしかありません。
 0+0=0
 0+1=1
 1+0=1
 1+1=10
つまり、「2通りの入力」が2つと、「4通りの結果」が1つです。

 対して、10進数1桁どうしの加算ルールは、0+0=0から始まって9+9=18まで、なんと100通りもあります。 「10通りの入力」が2つと、「100通りの結果」が1つです。

 機械や回路の事を知らなくても、2進数の加算回路と、10進数の加算回路、どちらが作りやすいか、明らかにお分かりでしょう。 2進数1桁は、0か1しか扱えませんが、先ほど述べた通り、たくさんの加算回路をつなげて、多くの桁を扱うようにすれば、いくらでも大きな数値を扱う事が出来るので、そこは問題になりません。

 また、0を1に、1を0に反転する回路も簡単に作れます。 加算回路と反転回路があれば、減算回路が作れます。
(参考 https://khurata.hatenablog.com/entry/2019/04/04/021054
 加算と減算が作れれば、乗算も除算も作れるので、これで計算機として使えるものが出来上がります。

 同じようなことを、10進数回路でやって出来なくはありませんが、かなり複雑な回路になってしまいます。

 

エンコーディング

 難しそうな小見出しですが、何も心配は要りません。 言葉が小難しいだけで、内容は大した事ではありません

 数値計算をするだけなら、2進数でも良いのですが、A とか B とかの文字をコンピュータで扱う場合は、ちょっと工夫が要ります。
 コンピュータが扱えるのは2進数だけですから、文字を表すためには、「どの文字を、どのような2進数の並びに対応させるか」を決めてやる必要があります。

 この決め事を、エンコーディング encoding符号化方式)と呼びます。

 たとえば ASCIIアスキー)という国際的な符号化方式では、A は 01000001、B は 01000010、C は 01000011、…と決められています。
 文字表現を2進数の並びに変換する動作を文字エンコード encode符号化)、2進数の並びを文字表現にする動作を文字デコード decode復号化)と呼びます。
 また、エンコーディングで決められた2進数の並びを、コード code符号)と呼びます。 ASCII という符号化方式における、文字 A のコード(符号)は、01000001 だ、という事になります。
(この辺の、言葉の使い方は、大切な「決め事」ですので、面倒だとは思いますが、憶えてしまうほうが、後々、いろいろとラクになると思います)

 通常、エンコードとデコードは、同じ決まり(エンコーディング、符号化方式)に従って行います。 何らかの文章を、ある符号化方式でエンコードした2進数の並び(コード)が有るとして、これを別の符号化方式によって表示(デコード)したら、「文字化け」になってしまうからです。

 今、ご覧になっている、この「知恵ノート」も、コンピュータの内部では2進数の並びでしかありません。 もちろん、その2進数の並びは、何らかの符号化方式によって文字エンコードされたものです。
 ウェブブラウザは、それと同じ符号化方式を自動的に選択し、それに従って文字デコードを行い、表示しています(後述)。 ですから、ウェブブラウザが、符号化方式を「誤認」して、エンコードとは異なる符号化方式のデコードをしてしまうと、文字化けになってしまいます。

 万一、そうなってしまった時に備えて、大抵のウェブブラウザでは、手動で符号化方式が選べるようになっています。  Internet Explorer ではメニューのページ→エンコードFirefox では表示→文字エンコーディングChrome では設定メニューのツール→エンコードSafari では現在ページメニュー→テキストエンコーディングで、符号化方式を強制選択出来ます。


 「コンピュータで文字を扱う」過程を、おおまかに言えば、次のようになります。

(1) 人間が入力した文字は、選ばれたエンコーディング(符号化方式)に従ってエンコード(符号化)され、2進数の並び(コード、符号)になって、コンピュータに伝えられる(これを実現するため、たとえばキーボードにはエンコーダ encoder符号化器)回路が内蔵されている)。

(2) コンピュータは、それが文字だとは思わず、あくまで2進数の並びとして処理をする。

(3) 人間に対して表示する時は、必要に応じてコードをデコード(復号化)する。通常、エンコードで使ったエンコーディング(符号化方式)に従ってデコードされる。

 上記の過程は、文字以外の表現でも同様です。 つまり、「2進数ではない何らかの表現」をコンピュータで処理するにはエンコードが必要であり、コンピュータの処理結果を「2進数でない何らかの表現」にする時は、デコードが必要なのです。

 

文字以外のエンコーディング

 文字表現だけでなく、小数を含む数値、画像や音声、動画などの表現も、それぞれに適した符号化方式が定められています。 また、コンピュータの処理能力の向上や、記憶領域の拡大といった、時代の移り変わりに従って、より改良された符号化方式が、次々と考え出されています。

 結局、文字・画像・音声・動画などのデータは全て、コンピュータにとっては「符号化された2進数の並び(コード)」でしかないのです。 コンピュータは、それが文字であるとか、画像であるとかを知らずに、ただひたすら2進数の並びを処理しているだけです。

 ただし、それぞれの表現に適した符号化方式には、それぞれ特有の「0と1の並びのパターン」があるので、「このコードは文字っぽい」「このコードは動画っぽい」という判断を、ある程度コンピュータにさせる事は出来ます。
 だから、データファイルをクリックするだけで、それに適した「再生ソフト」を、自動起動する事が出来るのです。 ワードファイルっぽい2進数の並びならワードを起動し、音声ファイルっぽい2進数の並びなら音楽プレーヤを起動する事が出来ます。
 もっとも、「これはいったい何だろう」という2進数の並びも有るわけで、そういう場合、適したプログラムを自動起動する事は出来ません。 そういう場合は、人間側が、適切と思われるプログラムを、手動で起動する必要があります。

 先ほど述べたような、「ウェブブラウザが文字エンコーディングを自動判別」する仕組みも似たようなもので、「この2進数並びだとシフトJIS っぽい」とか、「この並びは UTF-8 っぽい」という理由で、適したエンコーディングを選んでいるに過ぎません。
 しかし、全ての場合で絶対確実な選択が出来るわけでもないため、時としてウェブページが文字化けする事が有り、この場合は、妥当なエンコーディングを人間が指定してやる必要があるのです。

 

コーデック

 コーデックcodec)とは、コンピュータ・プログラムないしハードウェアの1つで、coder and decoder の略です。 訳せば「符号化・復号化をする者」というような意味になります。
 つまりこれは、ある符号化方式(エンコーディング)に従ってエンコードしたり、デコードをしてくれるモノであり、「エンコーディングを具現化したモノ」と言えます。

 文字や画像にもコーデックは有るのですが、文字や画像の代表的なエンコーディングは、現在、多くの OS に最初から内蔵されているため、我々がコーデックを意識する事は、あまり有りません(特殊な形式を除いては)。

 2013年現在、ほとんどのコンピュータが JPEG 画像を表示出来ますが、1990年代初期の PC 用 OS は、JPEGデコーダを内蔵しておらず、JPEG を表示出来ませんでした。 そのため、「JPEGローダ」というような、JPEG デコードをするプログラムが、別途開発され頒布されていました。 これは、JPEG のコーデックと言えます。


 しかし、音声や動画については、今もコーデックを意識する事があります。 それは、「再生出来ない音声、動画ファイル」に当たってしまった時です。

 なぜ再生出来ないかと言うと、そのファイルの内容の「2進数の並び」(コード)が、どのような符号化方式によって作られたのかを、コンピュータが知らない・判断出来ないからです。

 その対処方法は2通りあります。

 1つは、そのファイルを、自分のパソコンが知っている符号化方式にエンコードし直してもらう、つまりエンコードする事です(俗に「再エンコ」とも言う)。 ただし、「再」エンコードは、「いったんデコード→エンコード」という手順であるため、デコードが出来るパソコンでなければ行えません。

 もう1つは、その符号化方式を、自分のパソコンにインストールする事です。 これがつまり、「コーデックのインストール」です。

 

異なるエンコーディングの「利用」

 ここまでの話のポイントは2つあり、1つ目は、「コンピュータは2進数しか処理しない」ので、「何らかの表現を2進数の並び(符号)に置き換える」、「2進数の並び(符号)を何らかの表現に置き換える」という、2つの働きが必要であり、そのための決まり(符号化方式)が存在する、という事です。

 2つ目は、「コンピュータは、処理している2進数の並び(符号)が、文字か画像かなんて事は『知らない』、単なる2進数値として計算・処理している」という事です。

 これらを違う見方から言い変えると、「エンコードされた表現は、『コンピュータで計算可能な形』になっている」、と言うことが出来ます。
 文字を置き換えたり、画像を処理したり、動画を「再エンコ」したり、そういう事が可能なのは、それらが全て計算可能な値、つまりコンピュータ(計算機)が扱える2進値になっているからです。

 「計算」の結果を、どういうデコードで「表現」するか、その選択は、利用者ないしプログラマの自由です。
 エンコードと異なる符号化方式でデコードする、というのは、意図しない事であれば、「文字化け」とか「再生出来ない動画」ですけれども、意図して「異なるデコード」をすれば、画像を文字にしたり、文字を音声にする、という事が自在に出来るわけです。

 アナログ計算機は、アナログ表現を「処理」する事が出来ます。 たとえば画像処理や音声処理を、アナログ計算機は大変高速にこなします。 けれども、「画像を文字に」とか「文字を音声に」という事は、非常にやりづらいのです。

 対してディジタル計算機は、扱う表現を、いったん「2進値の並び(コード、符号)」にエンコードして扱います。 この「2進値の並び」は、文字でもなく、画像でもなく、音声でも動画でもありません。 つまり「2進値の並び」とは、それら全ての表現の「仲立ち」が出来る形式なのです(純粋情報とも言える)。

参考:下記ノート第6項 ディジタル・データ―「有限の立場」と標本化
https://khurata.hatenablog.com/entry/2019/04/04/044010

 ディジタル計算機が、非常に高速なアナログ計算機を駆逐した理由として、「ディジタル計算機はアナログ計算機を充分に模倣出来るから」、「ビット数を増やせば、容易に精度を上げられるから」、という2点がよく言われますが、私は、それに加えて、「エンコードとデコードを自在に組み合わせる事によって、表現を自在に変換出来るから」という理由も、非常に大きいと考えます。

 

おわりに

 いかがだったでしょうか……「エンコーディング」と聞くと、何だか小難しい感じがしますけれども、内容は大した事無いなぁ、と思っていただけたならば、本ノートの目的は達成です。
 コンピュータが表現しているあらゆるものは、全て、「2進数の並び」をデコードしたものに過ぎない……そう考えて、あらためてコンピュータを見てみれば、より賢く、コンピュータを使う事が出来るのではないかと思います。

 

付記:プログラムも「コード」である

 「コード」という言葉は、コンピュータ・プログラムの事を指すこともあります。 たとえばソースコードと言えば、それはソースプログラムの事ですし、マシンコードと言えば機械語プログラムの事です。

 なぜ、プログラムをコードとも言うのでしょうか。

 実行可能プログラム、つまり機械語メモリに置かれている「姿」を考えてみてください。 機械語も、エンコードされた文字や画像と同じように、メモリの中では「2進値の並び」という形になっています。 つまり、これも何らかの「コード(符号)」なのです。

 という事は、メモリ上の2進数の並びを、「『実行出来るプログラムとして』デコードするエンコーディング」が有るのではないか……と予想出来るでしょう。
 実際、その通りで、CPU には命令デコーダという回路があり、メモリから読み取った2進数の並びを、「その CPU が実行する命令として」デコードしています。 命令デコーダによってデコードされた結果が、「CPU の振る舞い」という表現、つまりプログラムの実行結果になるのです。
(もし、機械語プログラムを、文字エンコーディングに従ってデコードしてしまうと、文字の並びという表現になります)

 「CPU が異なると、機械語も異なる」というのは、異なる CPU は、異なる命令デコーダを持っているからです。 「CPU 毎に、採用している命令エンコーディングが異なる」と言っても良いでしょう。
 ですから、PowerPC プロセッサ用の機械語プログラムを、Pentium で実行させようとしても、それは無理なのです。 異なるエンコーディングによるプログラムコードだからです。 こんな事をしても「プログラムの文字化け」になるだけで、正しく実行出来ないのです。

 さて、命令デコーダは、多くの場合ハードウェアで実現されていますが(ですから高速に動作します)、コーデックの説明で述べた通り、これはソフトウェアで実現する事も出来ます。
 「ある CPU の命令デコーダ(というコーデック)を、ソフトウェアで作ったもの」、それが、エミュレータとか、仮想マシンと呼ばれるものです。

 エミュレータが実現出来るのも、「情報を2進数の並び(コード)という『仲立ち』形式で扱う」ディジタル計算機ならではです。

 こうした見方は、高級言語であっても成り立ちます。 インタプリタスクリプトエンジンは、その言語で書かれた(エンコードされた)ソースコードを、「実行出来るプログラムとしてデコード」している、と言えます。
 CPU が機械語命令をデコードしているように、インタプリタスクリプトエンジンは高級言語の式や文をデコードしているのです。 だからこそ、そのプログラムは「動く」のです。
 対して、アセンブラコンパイラは、ソースコードを異なるエンコーディング機械語命令コード)に変換しているだけ、つまり「再エンコ」しているだけだと言えます。

 

履歴

  • ASCII 文字コード値が間違っていたのを訂正しました。(2013/07/16)
  • 付記に、高級言語についての文言を追加しました。(2013/10/10)

(転載以上)