nslua.dllでbit演算
取り急ぎ。後で解説を追加する。
本体
do local bit = 8 -- 8ビットまでのxor計算をする。 local base_table = {1} -- 桁毎の数値を入れておく。 while bit > #base_table do -- 基数テーブルを作る。 base_table[1+#base_table] = base_table[#base_table] * 2 end local logic = function(box, base) if box.a < base then box.af = false else box.af = true box.a = box.a - base end if box.b < base then box.bf = false else box.bf = true box.b = box.b - base end end local make_box = function(a, b) local box = {} box.a = a box.b = b return box end local bit_not = function(num) -- 一つの数値を受け取り、ビット反転して返す。 local res = 0 for i = bit, 1, -1 do if num < base_table[i] then res = res + base_table[i] else num = num - base_table[i] end end return res end math.bit_not = bit_not local bit_and = function(numa, numb) -- 二つの数値を受け取り、それをandして返す。 local box = make_box(numa, numb) local res = 0 for i = bit, 1, -1 do logic(box, base_table[i]) if box.af and box.bf then res = res + base_table[i] end end return res end math.bit_and = bit_and local bit_or = function(numa, numb) -- 二つの数値を受け取り、それをorして返す。 local box = make_box(numa, numb) local res = 0 for i = bit, 1, -1 do logic(box, base_table[i]) if box.af or box.bf then res = res + base_table[i] end end return res end math.bit_or = bit_or local bit_xor = function(numa, numb) -- 二つの数値を受け取り、それをxorして返す。 local box = make_box(numa, numb) local res = 0 for i = bit, 1, -1 do logic(box, base_table[i]) if box.af then if box.bf then else res = res + base_table[i] end else if box.bf then res = res + base_table[i] else end end end return res end math.bit_xor = bit_xor local bit_xand = function(numa, numb) -- 二つの数値を受け取り、それをxandして返す。 local box = make_box(numa, numb) local res = 0 for i = bit, 1, -1 do logic(box, base_table[i]) if box.af then if box.bf then res = res + base_table[i] else end else if box.bf then else res = res + base_table[i] end end end return res end math.bit_xand = bit_xand string.bit_not = function(str) local res = {} for i, letter in ipairs({str:byte(1, str:len())}) do res[i] = string.char(bit_not(letter)) end return table.concat(res) end string.bit_xor = function(str, key) local res = {} local keys = {key:byte(1, key:len())} local key_num = 1 for i, letter in ipairs({str:byte(1, str:len())}) do res[i] = string.char(bit_xor(letter, keys[key_num])) key_num = key_num + 1 if type(keys[key_num]) == "nil" then key_num = 1 end end return table.concat(res) end end
- math.bit_not
- math.bit_and
- math.bit_or
- math.bit_xand
- math.bit_xor
- string.not
- string.xor
を追加する。math系のnot以外は数値を二つ渡して名前のとおりの処理をした後結果を一つ返す。notは引数を一つだけ取る。
string.notは、ある文字列に対して全ての文字の文字コードをnot処理して返す。そのため、8bitしか扱わないように制限してある。
string.xorは、第二引数として別の文字列を与える。それを使ってxor処理して返す。
string系で注意しなければならないのは、変換した結果に文字コード0が含まれた場合であり、それをNScripterの文字列変数に渡すとそこで文字列が切れてしまうことである。
よって、string系で変換した内容は、Luaの中だけで扱うようにするのが無難である。
文字列をなんちゃって暗号化する
NSExec("luasub coding") function NSCOM_coding() local res = NSPopStrRef() NSPopComma() local str = NSPopStr() NSSetStrValue(res, string.bit_not(str)) end
NScripter側にcoding命令を追加する。
codingでなんちゃって暗号化した文字列は、もう一度codingに渡すことで元の文字列に戻る。