zatsu na benkyou matome saito

勉強したことをまとめるだけのサイト、数学、プログラミング、機械学習とか

2進数: ビット、バイト、そして情報の表現:教養としてのコンピューターサイエンス講義 今こそ知っておくべき「デジタル世界」の基礎知識

2進数: ビット、バイト、そして情報の表現

今読んでいる書籍で、コンピュータがどのように複雑な文字や、絵文字などを理解しているかを知ることができた。 今まで2進数をフワッとしか理解していなかったのでこれを読んでかなり具体的に理解できた。2進数について理解することで、ドラクエ復活の呪文の仕組みも容易に理解することができた。

参考: ファミコンの復活の呪文はどういう仕組みでプレイデータを記録していたのでしょうか…? - Quora

本タイトル: 教養としてのコンピューターサイエンス講義 今こそ知っておくべき「デジタル世界」の基礎知識

皆さんご存知の通り、PCは基本的に [0, 1] の2進数の情報しか読み取ることができない。では、どうやって「今日はいい天気でした。」という日本語を機械に読み取らせることができるのか? それは単純で、日本語の文章を機会が読み取ることができる形に変換すればいよい。Googleで「日本語 2進数 変換」とかググるといくらでも変換サイトが出てくると思うので気になったら試していただきたいのだが、先ほど例で出した「今日はいい天気でした。」という日本語を2進数に直すと、「10111010101000111100011011111100101001001100111110100100101001001010010010100100110001011011011110110101101001001010010011000111101001001011011110100100101111111010000110100011」という0,1の羅列になる。このように人間が理解できる情報を、機会が理解できるようにするまでの作業を「コンパイル」という。エンジニアの方はよく耳にするだろうが、C言語Java、フロントエンドのJavaScriptなどをコンパイルを行って機会が読み取れるように変換する作業がある。フロントエンドの場合は、TypeScriptで書かれたJSをバニラJSにコンパイルするというように使われていると思うが、、、(定かではない。)

とこのように、それぞれの文章を0,1で表すことでPCに何を入力したか、何が出力されたかなどを理解させている。

プログラミンを勉強するときによく使われる。

print("Hello World")

などもコンパイルされると0,1の2進数になる。

ビット、バイト、バイナリー

ビット

世界には10種類の人間しかいない、2進数(バイナリーナンバー)を理解している人とそうでない人だ。

という言葉があるが、これは10の部分が2進数で表されており、10 -> 2となるので2種類しかいないよ。というのを言っているだけである。

1ビットは0 or 1のどちらかで値を取る時の単位:2種類 2ビットは、00, 01, 10, 11の4つで値を取る時の単位:4種類 3ビットは、000, 001, 010, 011, 100, 101, 110, 111:8種類 ・ ・ ・ nビットは。。。

のようにそれぞれのビットは2進数を使うときの桁数を表している。 それぞれのビット数が増えるごとにあるパターンが見えてくる。

それは、

1ビット = 2
2ビット = 4
3ビット = 8
4ビット = 16
・・・
nビット = ?

nビットのところに何が入るかというと、

2^{n}である。

なので、それぞれ

1ビット = 2^{1} = 2

2ビット = 2^{2} = 4

3ビット = 2^{3} = 8

4ビット = 2^{4} = 16

・・・

nビット = 2^{n} = 2^{n}

というパターンが見えてくる。

2(進数)の累乗と、10(進数)の累乗にはある程度に通った関係性があるので、ある程度の数字までは覚えておくと良い。 これは特にIT関連の仕事をしていると、1KB = 1024なのか、1KB = 1000なのかであやふやなところがあるが、それはこの関係性のためである。

f:id:dorcushopeino1:20210704130904p:plain

2進数

ビットの箇所でも既に出てきているのである程度理解されていると思うが、基本情報技術者試験などで出てくる2進数を10進数に直しなさい。 みたいな問題は特に理解するのがめんどくさかった。なぜなら、この数字変換をいつ使うのかが全くわからなかったからである。

今後はPCを使って作業するので2進数 -> 10進数に変換することや、その逆を手作業でやることはないだろうが、PCがどのように10進数を理解しているか、どのように他の情報を理解しているかを理解しやすいために知っておいて損はない情報である。

10進数の1867は、  1 * 10^{3} + 8 * 10^{2} + 6 * 10^{1} + 7 * 10^{0}というように表されるので、10の累乗の合計を表したものになる。

2進数の場合も同じで、(ただし、底が10ではなく、2である)11101のような2進数を表したい場合は 1 * 2^{4} + 1 * 2^{3} + 1 * 2^{2} + 0 * 2^{1} + 1 * 2^{0}と解釈される。

これを10進数で表現すると、

16 + 8 + 4 + 0 + 1 = 29となる。

指で2進数を表す

両手に5本ずつ指があり、合計10本の指がありますがそれらの指で数えられる2進数の範囲はどれくらいになるでしょうか?

答えは、2^{10}通りとなります。 それぞれの指を1ビットと解釈すれば、我々両手に10ビットの情報量を持っていることになります。

親指 = 0, 1 人差し指 = 0, 1 中指 =

と、それぞれの指に0, 1の情報量を持っています。

本書で紹介されていた132という数字を指で表すとすると、

「0010000100」

という表記になり、これは両手の中指を立てた状態になります。

2進数 -> 10進数 変換

2進数を10進数に変換するのは、「対応するビットが1になっているくらいの、2の累乗を合計するだけ。」です 10進数を2で繰り返し割っていき、この時の余剰を書きとめます。2で割っているのでこれは0, 1のどちらかになります。

そして割り算の結果の商を次にわる対象の値にします。元の数値が0になるまで割り続けてください。 途中書き留めた余剰の列が求める2進数です。ただし順序が逆になっているので、それを反転させてください。

例として1867を2進数に変換すると画像のように余剰が求められ、それを反転させると下から「11101001011」という2進数を求めることができる。

f:id:dorcushopeino1:20210704132544p:plain

ドラクエ復活の呪文について

(ちゃんと調べてない予測です。本来は違うかもしれません。)

復活の呪文の件ですが、実際には20文字以上のひらがなの羅列になるので以下のようのな感じになります。

からず わちぶ ばひせご
こずと てにち ひ

それぞれのドラクエのパラメータをこれで管理している。

例えば、以下のようなパラメータが存在するとする。

{
  "進捗管理": {
    "ステージ": 2,
    "サブステージ": 10
  },
  "勇者": {
    "ステータス": {
      "攻撃": 120,
      "防御": 210,
      "MP": 20,
      "HP": 2000
    },
    "持ち物": {
      "魔法の杖": 1,
      "勇者の剣": 0
    }
  }
}

それぞれの管理する値を

ステージ = 1文字目
サブステージ = 2文字目
勇者.ステータス = 3文字目
...

のように管理する場所が決まっているとすると、

8文字のひらがなの羅列が必要である。(上から順に必要なパラメータを左から右に羅列したものとする。)

そうすると、

2 10 120 210 20 2000 1 0

という羅列ができる。

これで管理するのでもよさそうだが、これだとどのパラメータを表しているのかあからさまで、ゲームハックされやすいし、 もしかしたら管理しているパラメータがもっと多い可能性がある。

そのため、ひらがなに変換して、脆弱性を回避する。(脆弱性という言葉は適切ではないだろうが、上手い表現が見つからなかった)

どのようなアルゴリズムを使用しているかは不明だが、こちらのサイト( 47進いろは記数法⇔10進法 変換機)でそれぞれの数値をひらがなに変換すると、

2 = ろ
10 = ぬ
120 = ろの
210 = にら
20 = ね
2000 = しの
1 = い
0 = す

と変換でき、復活の呪文が生成される。

ろぬろの にらねしの いす

というのが今回のふっかつの呪文である。

実際には、このひらがなの羅列を2進数までコンパイルして それぞれがなんのパラメータなのかをPCが認識し、ゲームに反映している。

その他参考資料

Unicodeがそれぞれどのコードに結びついているかの一覧 home.unicode.org