昔のゲームに出てきそうなひらがな(64種)による暗号です。
ひらがな1文字(16ビット)で6ビットの情報が表現できますので、情報量は16/6=約2.7倍になります。妙にビット演算が多いので、単純な目的の割に複雑なスクリプトになっています。
カタカナも取り入れれば7ビットの情報が表現できるはずです。また、半角カタカナを使えば情報量を8/6=約1.3倍に抑えられます半角カタカナは濁点・半濁点の表現に1ビット要するので一概には言えません。
復元時にinstrによる線形検索を行っているなど、速度上の課題はまだまだあるでしょう。// 文字列型暗号作成スクリプト
// 参考:テキストボックスの編集監視
// http://lhsp.s206.xrea.com/hsp_object2.html#4
#define ctype HIWORD(%1) (%1 >> 16 & 0xFFFF)
#module
#include "hspmath.as"
#const SPELL_KEY 0
// モジュールの初期化
#deffunc init_spell
// 文字列型暗号の素 64文字
sdim base, 64 * 2 + 1
base = "あいうえおかきくけこがぎぐげごさしすせそざじずぜぞ" // 25文字
base += "たちつてとだぢづでどなにぬねのはひふへほばびぶべぼ" // 25 + 25 = 50文字
base += "まみむめもやゆよらりるれろん" // 50 + 14 = 64文字
return
// 指定した位置(ビット)から6ビットを取り出すマクロ
// バッファオーバーフローに注意
#define ctype peek6(%1, %2=0) ((((peek(%1, (%2) / 8) << 8) | peek(%1, 1 + (%2) / 8)) >> (10 - (%2) \ 8)) & 0x3F)
// 指定した位置(ビット)から6ビット書き込む命令
// バッファオーバーフローに注意
#deffunc poke6 var target, int index, int value
i = (peek(target, index / 8) << 8) | peek(target, index / 8 + 1)
i ^= peek6(target, index) << (10 - (index \ 8))
i |= (value & 0x3F) << (10 - (index \ 8))
poke target, index / 8, (i >> 8) & 0xFF
poke target, index / 8 + 1, i & 0xFF
return
// パスワードから通常の文字列データへ変換
#deffunc spell2str var result, str _before
before = _before
len = strlen(before)
randomize SPELL_KEY
repeat len / 2
code = (instr(base, 0, strmid(before, cnt * 2, 2)) / 2) ^ rnd(0x40)
poke6 result, cnt * 6, code
loop
poke result, int(ceil(8.0 * len / 6.0)), 0
return
// 通常の文字列データからパスワードに変換
#deffunc str2spell var result, str _before
before = _before
randomize SPELL_KEY
// 対象となる文字列から6ビットずつ切りだし、ひらがなに変換
for i, 0, strlen(before) * 8, 6
// XOR演算によって より暗号っぽく
wpoke result, i / 3, wpeek(base, (peek6(before, i) ^ rnd(0x40)) * 2)
next
poke result, i / 3, 0
return
#global
init_spell
screen 0, 240, 200
// 元の文字を代入する文字列型変数
sdim before, 512
// 文字列型暗号が代入される文字列型変数
sdim result, 1536
// テキストボックス作成
mesbox before, ginfo_winx, ginfo_winy / 2, , 250
hInput = objinfo_hwnd(stat)
mesbox result, ginfo_winx, ginfo_winy / 2
idResult = stat
sendmsg objinfo_hwnd(idResult), $CF, 1 // 編集無効
oncmd gosub *command, 0x0111 // WM_COMMAND
stop
// テキストボックスの編集を監視する
*command
if lparam == hInput {
if HIWORD (wparam) = 0x300 {
// 編集された場合は文字列型暗号を作って表示
str2spell result, before
objprm idResult, result
/* // この行の"/*"を消すとタイトルに復元した文字列を表示
sdim s, 512
spell2str s, result
title s
//*/
}
}
return
2008年1月17日木曜日
「ふっかつのじゅもん」っぽい暗号
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿