Hannya64

本記事はクソアプリ2 Advent Calendar 2020の24日目の記事です。

Hannya64

https://inabajunmr.github.io/Hannya64/

デモ

f:id:inabajunmr:20201201235121g:plain

Base64の実装

注意

  • 筆者は普段こういうコードを全く書かないので、なんか間違ってたら教えて下さい
  • 効率とかは全然意識してないです
  • パディングとかURLエンコードの話とかはないです

基本的な方針

バイト列を先頭から3バイト取り出し、6ビット4つに変換する。6ビット(0〜63)を、文字列にマッピングしていく。

こちらを参考にさせてもらいました。

Algorithm Implementation/Miscellaneous/Base64 - Wikibooks, open books for an open world

実装

エンコード前のバイト配列を以下とする。

10000000 11000000 11100000 11110000 11111000 11111100

3バイトずつ処理する。最初は先頭の3バイトを処理する。

10000000 11000000 11100000

3バイトをくっつけて24ビットにする。 まず1バイト目を16ビット左シフトする。

10000000 << 16

結果右に0が16個くっついて以下になる。

        <---------------
100000000000000000000000

2バイト目を8ビット左シフトする。

                <-------
000000001100000000000000

3バイト目はそのまま。

000000000000000011100000

1つ目と2つ目をORでつなぐ。

100000000000000000000000 |
000000001100000000000000

ビット演算子のORは、いずれかが1だったら1になるので、以下のようになる。

100000001100000000000000

つないだ結果と3つ目もORでつなぐ。

100000001100000000000000 |
000000000000000011100000

結果、24ビットの列ができる。

100000001100000011100000

24ビットの列を18ビット右シフトして6ビット取り出す。

100000001100000011100000 >> 18

右シフトすると、左から0が詰められて右側のビットはあふれて消えるので、以下のようになる。

----------------->
000000000000000000100000

24ビットの列を12ビット右シフトして次の6ビットを取り出す。

----------->
000000000000100000001100

001100 だけを取り出したいので、111111 とANDで右から6桁だけ取り出す。

000000000000100000001100 &
000000000000000000111111

ANDは両方とも1だった時だけ1になるので以下になる。

000000000000000000001100

同じようにして次の6ビットも取り出す。

100000001100000011100000 >> 6 & 000000000000000000111111

最後の6ビットも同様に取り出す。最初の24ビットのうち、最後の6ビットを取り出せばよいので右シフトは不要となる。

100000001100000011100000 & 000000000000000000111111

この結果、この3バイトが

10000000 11000000 11100000

6ビット4つに変換できる。

100000 001100 000011 100000

6ビットなので、ここで得たそれぞれの値は000000(0)から111111(63)の64パターンになる。 10進数に変換すると以下になる。

32 12 3 32

以下のような文字列を用意する。

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

A が0で、/ が63として文字列のインデックスと数値の対応を変換すると以下になる。

gMDg

残った3バイトも同じ方法で変換していくと以下になる。

gMDg8Pj8

コード

Hannya64/hannya64.js at main · inabajunmr/Hannya64 · GitHub