18
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

復活の呪文を実装してみた

Last updated at Posted at 2019-05-21

復活の呪文とは

データを64種類のひらがなから成る文字列に変換し、紙などに記録する保存方式である。主に記録用電子媒体が存在しない環境で用いられた。

使用する文字

ぴったり64種類1なので、6ビットの情報を表現できる。

あいうえお まみむめも やゆ
かきくけこ らりるれろ よわ
さしすせそ がぎぐげご
たちつてと ざじずぜぞ
なにぬねの ばびぶべぼ
はひふへほ ぱぴぷぺぽ

変換形式

  • 元データを6ビットずつに分割(6ビットに満たない分は0を追加して6ビットにする)
  • 変換表を使って各6ビットの値を変換

↓これが

abc

↓こうなって

01100001 01100010 01100011
011000 010110 001001 100011

↓こうなる

のぬこら

って、これまんまBase64じゃん

Base64は、データを64種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式である。

単なる偶然ではなさそうですね?2

実装してみる

使用する文字

理解も兼ねてクラス化してみた。復活エンコーダー。

fukkatsu.py
class FukkatsuEncoder:
    __USABLE_CHARS = \
        'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほ' \
        'まみむめもらりるれろがぎぐげござじずぜぞばびぶべぼぱぴぷぺぽ' \
        'やゆよわ'

復活の呪文に変換する

内部で2進数を表現する「文字列」に変換しているので、わかりやすい代わりに効率は悪い。

fukkatsu.py
def encode(self, raw: bytes) -> str:
    b = ''.join(map(lambda c: format(c, '08b'), raw))
    # 6の倍数になるようゼロ埋めする
    b += '00000'
    b = b[0:-(len(b)%6)]
    # 連番が偶数となる要素は空文字なので除外する
    encoded = ''.join(map(lambda c: self.__USABLE_CHARS[int(c, 2)], \
                          re.split('(.{6})', b)[1::2] \
    ))
    return encoded

復活の呪文から元データを復元する

なんか動かない

fukkatsu.py
def decode(self, encoded: str) -> bytes:
    b = ''.join(map(lambda c: format(self.__USABLE_CHARS.find(c), '06b'), \
                    encoded))
    # 8の倍数に満たない場合、末尾は捨てられてしまうので問題なし
    raw = ''.join(map(lambda i: chr(int(i, 2)), \
                  re.split('(.{8})', b)[1::2]))
    return raw

decode()の引数に「あいう」を渡すと以下のエラー。

UnicodeEncodeError: 'cp932' codec can't encode character '\xe3' in position 0: illegal multibyte sequence

文字列とバイト列は別物

バイトを文字に変換chr()してから結合join()しているので、マルチバイト文字の場合がダメでした。ここはバイト列bytes()を作ってから、必要に応じて文字列に変換するのが正解。

fukkatsu.py
    raw = bytes(map(lambda i: int(i, 2), \
                re.split('(.{8})', b)[1::2]))

ソースコード

Gistに置いておきました。decode()のバグっていたリビジョンも残してあります。
https://gist.github.com/cress-cc/985dc5923686e21f19ee14a57129ade4

これは何の役に立つのか

何の役にも立ちません。

  1. 一般人には伝わらない感覚

  2. Base64 - Wikipedia

18
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?