はじめに
復活の呪文とは、ゲーム機にセーブデータを保存できなかった頃、20文字のひらがな列をセーブデータにする仕組みで、ドラクエ1で使われていた。仕組みは下記サイトに解説されている。
112bitのセーブデータにCRC-16-CCITTで8bitのチェックコードを付けて120bitのデータをベースにして、bit列の順番を入れ替えるなどの暗号化をし、最後に6bitずつの64種類のひらがなコードに変換して、20文字(120bit/6=20)にしたものである。本時記事は、「64種類のひらがなコードに変換」に着目したお遊び記事。
Base64とは
64種類の文字を扱うエンコード技術としてBase64がある。マルチバイト文字やバイナリーデータなどを英数字64種類の文字列に変換する仕組みで、メールの伝送等で使われる技術。
参考
Pythonのbase64
モジュールを使えば簡単に変換ができる。例えば 文字列 こんにちは
は Base64で 44GT44KT44Gr44Gh44Gv
となる。
import base64
input_data = 'こんにちは'
# utf-8に変換
b64databytes = base64.b64encode(input_data.encode('utf-8'))
# Base64変換
b64datastr = b64databytes.decode('utf-8')
print(b64datastr)
# 44GT44KT44Gr44Gh44Gv
復活の呪文への変換
復活の呪文は64文字のひらがなに変換するので、Base64の変換コードの代わりにひらがなを使えば、復活の呪文ぽくなると思う。ということで、下記のテーブルで変換してみる。Base64のパディングの=
は、ん
に変換することとした。
マルチバイトを伝送するためにBase64の技術があるのに、マルチバイトのひらがなに変換したら意味ないでしょ!という突っ込みはあると思いますが、お遊びということで許してください。
excahge_dic={
'A':'あ','B':'い','C':'う','D':'え','E':'お',
'F':'か','G':'き','H':'く','I':'け','J':'こ',
'K':'さ','L':'し','M':'す','N':'せ','O':'そ',
'P':'た','Q':'ち','R':'つ','S':'て','T':'と',
'U':'な','V':'に','W':'ぬ','X':'ね','Y':'の',
'Z':'は','a':'ひ','b':'ふ','c':'へ','d':'ほ',
'e':'ま','f':'み','g':'む','h':'め','i':'も',
'j':'や','k':'ゆ','l':'よ',
'm':'ら','n':'り','o':'る','p':'れ','q':'ろ',
'r':'わ',
's':'が','t':'ぎ','u':'ぐ','v':'げ','w':'ご',
'x':'ざ','y':'じ','z':'ず','0':'ぜ','1':'ぞ',
'2':'ば','3':'び','4':'ぶ','5':'べ','6':'ぼ',
'7':'ぱ','8':'ぴ','9':'ぷ','+':'ぺ','/':'ぽ',
'=':'ん'
}
Pythonのコードにすると、下記な感じ。
復活の呪文風Base64変換
👇
べふぼれべわてぱぶぶきぐべはきろべれひくぼひさるちらかずはとのぜべひてこべるぺふ
となる。
import base64
def fukkatsu_no_jyumon(data_str, encdec='encode', fukkatsu='on'):
Ret=''
# [Base64⇔ひらがな]変換
def base64_with_fukkatsu(data_str, encdec='encode'):
excahge_dic={
'A':'あ','B':'い','C':'う','D':'え','E':'お',
'F':'か','G':'き','H':'く','I':'け','J':'こ',
'K':'さ','L':'し','M':'す','N':'せ','O':'そ',
'P':'た','Q':'ち','R':'つ','S':'て','T':'と',
'U':'な','V':'に','W':'ぬ','X':'ね','Y':'の',
'Z':'は','a':'ひ','b':'ふ','c':'へ','d':'ほ',
'e':'ま','f':'み','g':'む','h':'め','i':'も',
'j':'や','k':'ゆ','l':'よ',
'm':'ら','n':'り','o':'る','p':'れ','q':'ろ',
'r':'わ',
's':'が','t':'ぎ','u':'ぐ','v':'げ','w':'ご',
'x':'ざ','y':'じ','z':'ず','0':'ぜ','1':'ぞ',
'2':'ば','3':'び','4':'ぶ','5':'べ','6':'ぼ',
'7':'ぱ','8':'ぴ','9':'ぷ','+':'ぺ','/':'ぽ',
'=':'ん'
}
if(encdec == 'encode'):
# Base64文字列をひらがなに変換
return ''.join([excahge_dic.get(c, c) for c in data_str])
elif(encdec == 'decode'):
# 逆引き辞書を作成
reverse_dic = {v: k for k, v in excahge_dic.items()}
# ひらがな文字列をBase64に変換
return ''.join([reverse_dic.get(c, c) for c in data_str])
if(encdec == 'encode'):
# Base64変換
b64databytes = base64.b64encode(data_str.encode('utf-8'))
b64datastr = b64databytes.decode('utf-8')
# 復活の呪文変換
if(fukkatsu=='on'):
Ret = base64_with_fukkatsu(b64datastr,encdec)
else:
Ret = b64datastr
elif(encdec == 'decode'):
# 復活の呪文変換
if(fukkatsu=='on'):
data_str = base64_with_fukkatsu(data_str,encdec)
else:
pass
# Base64変換
b64databytes = base64.b64decode(data_str)
b64datastr = b64databytes.decode('utf-8')
Ret = b64datastr
else:
Ret = 'Error'
return Ret
input_data = '復活の呪文風Base64変換'
print(f'■indata:\n{input_data}\n')
b64encdata = fukkatsu_no_jyumon(input_data,'encode','off')
print(f'■Base64enc:\n{b64encdata}\n')
b64encdata_with_fukkatsu = fukkatsu_no_jyumon(input_data,'encode','on')
print(f'■呪文enc:\n{b64encdata_with_fukkatsu}\n')
b64decdata = fukkatsu_no_jyumon(b64encdata,'decode','off')
print(f'■Base64dec:\n{b64decdata}\n')
b64decdata_with_fukkatsu = fukkatsu_no_jyumon(b64encdata_with_fukkatsu,'decode','on')
print(f'■呪文dec:\n{b64decdata_with_fukkatsu}\n')
# ■indata:
# 復活の呪文風Base64変換
#
# ■Base64enc:
# 5b6p5rS744Gu5ZGq5paH6aKoQmFzZTY05aSJ5o+b
#
# ■呪文enc:
# べふぼれべわてぱぶぶきぐべはきろべれひくぼひさるちらかずはとのぜべひてこべるぺふ
#
# ■Base64dec:
# 復活の呪文風Base64変換
#
# ■呪文dec:
# 復活の呪文風Base64変換
以上