|
| 1 | +minicrypto = {} |
| 2 | + |
| 3 | +local insert, concat, modf, tostring, char = table.insert, table.concat, math.modf, tostring, string.char |
| 4 | + |
| 5 | + |
| 6 | +local function numberToBinStr(x) |
| 7 | + local ret = {} |
| 8 | + while x~=1 and x~=0 do |
| 9 | + insert(ret, 1, x%2) |
| 10 | + x=modf(x/2) |
| 11 | + end |
| 12 | + insert(ret, 1, x) |
| 13 | + for i = 1, 8 - #ret do |
| 14 | + insert(ret, 1, 0) |
| 15 | + end |
| 16 | + return concat(ret) |
| 17 | +end |
| 18 | + |
| 19 | +local function computeBinaryKey(str) |
| 20 | + local t = {} |
| 21 | + for i = #str, 1, -1 do |
| 22 | + insert(t, numberToBinStr(str:byte(i,i))) |
| 23 | + end |
| 24 | + return concat(t) |
| 25 | +end |
| 26 | + |
| 27 | +local binaryKeys = setmetatable({}, {__mode = "k"}) |
| 28 | + |
| 29 | +local function binaryKey(key) |
| 30 | + local v = binaryKeys[key] |
| 31 | + if v == nil then |
| 32 | + v = computeBinaryKey(key) |
| 33 | + binaryKeys[key] = v |
| 34 | + end |
| 35 | + return v |
| 36 | +end |
| 37 | + |
| 38 | +local function initialize_state(key) |
| 39 | + local S = {}; for i = 0, 255 do S[i] = i end |
| 40 | + key = binaryKey(key) |
| 41 | + |
| 42 | + local j = 0 |
| 43 | + for i = 0, 255 do |
| 44 | + local idx = (i % #key) +1 |
| 45 | + j = (j + S[i] + tonumber(key:sub(idx, idx))) % 256 |
| 46 | + S[i], S[j] = S[j], S[i] |
| 47 | + end |
| 48 | + S.i = 0 |
| 49 | + S.j = 0 |
| 50 | + return S |
| 51 | +end |
| 52 | + |
| 53 | +local function encrypt_one(state, byt) |
| 54 | + state.i = (state.i+1) % 256 |
| 55 | + state.j = (state.j + state[state.i]) % 256 |
| 56 | + state[state.i], state[state.j] = state[state.j], state[state.i] |
| 57 | + local K = state[(state[state.i] + state[state.j]) % 256] |
| 58 | + return K ~ byt |
| 59 | +end |
| 60 | + |
| 61 | +function minicrypto.encrypt(text, key) |
| 62 | + local state = initialize_state(key) |
| 63 | + local encrypted = {} |
| 64 | + for i = 1, #text do |
| 65 | + encrypted[i] = ("%02X"):format(encrypt_one(state, text:byte(i,i))) |
| 66 | + end |
| 67 | + return concat(encrypted) |
| 68 | +end |
| 69 | + |
| 70 | +function minicrypto.decrypt(text, key) |
| 71 | + local state = initialize_state(key) |
| 72 | + local decrypted = {} |
| 73 | + for i = 1, #text, 2 do |
| 74 | + insert(decrypted, char(encrypt_one(state, tonumber(text:sub(i, i+1), 16)))) |
| 75 | + end |
| 76 | + return concat(decrypted) |
| 77 | +end |
0 commit comments