while thinking of an idea to create an encryption/cipher method, I thought of one that I wondered existed already. The method I imagined was to have pre-set characters, but instead, randomly generate meanings for these characters.
Here's what I mean: (Representation in Lua)
local Keys = {'a','b','c',} -- Rest of table removed for simplicity
for i,v in pairs(Keys) do
Keys[v] = ''
repeat
if Key[v] then
Keys[v] = Keys .. string.char(math.random(1,255))
else
Keys[v] = string.char(math.random(1,255))
end
until string.len(Keys[v]) == 4
end
print(Keys) --> {'a' = "ą�vź",..}
Then when you make a string and transcribe it with the Keys table, it'll come out as the meaning given to it. Pretty simple, could probably do more with it, but does something like this already exist (have an official name for the method, perhaps?)
Passwordless obfuscating is also done with ROT.
Just for fun i do this...
-- rot.lua
-- Usage: Creates a table (i.e. rot) for using it with string.gsub('Hello World','(.)',rot)
-- A '.' in gsub() is neccessary to hit every single char in a string
-- ROT13 for chars, ROT5 for numbers, ROT8/ROT3/ROT2/ROT1 for signs
-- IMPORTANT: Both key/value pairs has to be datatype string
local args={...}
local rotator=function(...)
local args, rot, c ={...}, {}, ''
-- ROT5 for numbers
for i=48,52 do rot[c.char(i)]=c.char(i+5) end
for i=53,57 do rot[c.char(i)]=c.char(i-5) end
-- ROT13 for chars (upper and lower case)
-- Uppercase letters (ROT13)
for i=65,77 do rot[c.char(i)]=c.char(i+13) end
for i=78,90 do rot[c.char(i)]=c.char(i-13) end
-- Lowercase letters (ROT13)
for i=97,109 do rot[c.char(i)]=c.char(i+13) end
for i=110,122 do rot[c.char(i)]=c.char(i-13) end
-- Signs (ROT8)
for i=32,39 do rot[c.char(i)]=c.char(i+8) end
for i=40,47 do rot[c.char(i)]=c.char(i-8) end
-- Signs (ROT3)
for i=58,60 do rot[c.char(i)]=c.char(i+3) end
for i=61,63 do rot[c.char(i)]=c.char(i-3) end
-- Signs (ROT2)
for i=91,92 do rot[c.char(i)]=c.char(i+2) end
for i=93,94 do rot[c.char(i)]=c.char(i-2) end
-- Sign # and tabstop (ROT1)
rot['\t']='#'
rot['#']='\t'
return args[1]:gsub('.',rot),rot
end
local _,rot=rotator('koyaanisqatsi') -- Extracting the rot table from function rotator
if #args==2 and args[2]==':preload:' then
table.insert(rot,rotator)
return rot
else
return rotator
end -- Conditional return when required and package.preload is triggered
If required und furthermore in string table as: string.rot you can obfuscating and deobfuscating with the same function...
> myvar='koyaanisqatsi'
> print(myvar)
koyaanisqatsi
> myvar=myvar:rot()
> print(myvar)
xblnnavfdngfv
> myvar=myvar:rot()
> print(myvar)
koyaanisqatsi
I am developing a turn-based game and I have a player table of the following structure
players = {
["p1"] = Player(),
["p2"] = Player(),
...
["pn"] = Player()
}
What I wanted to do is iterate through each players in the table (after each player played his round) and get back to the first index ("p1" in this case)
So it should do the following stuff when I run the code
function shift()
-- do stuff to shift the player's turn
print(player.name)
end
shift() -- "p1"
shift() -- "p2"
...
shift() -- "pn"
shift() -- "p1"
-- and so on
local index
function shift()
if not index then index = next(players) end
print(players[index].name)
index = next(players, next)
end
That should do what you want, if I understood the question correctly ;)
EDIT:
As Egor Skriptunoff pointed out in his comment, you can also have the function return the key and use and instead of an if:
local index
function shift()
index = next(players,index)
return index or next(players)
end
Your loop should be something along the lines of:
for k, player in pairs(players) do
player:Player()
end
If you want to recall the the first players function then just follow this with:
players[1]:Player()
Hope this helped!
Edit: To make it endless, just put it in a 'repeat until loop' so it would look something like:
repeat
<for loop across all players>
until <condition>
I have 2 strings:
fields="a,b,c,d,e"
values="1,2,,4,5"
I need a table, to get the pairs values like:
print(result.a) -> "1"
print(result.c) -> "" (or nil)
Is it possible?
Here is an opportunity to exploit generators without a for loop. The code below runs two gmatch generators in tandem.
fields="a,b,c,d,e"
values="1,2,,4,5"
fields=fields.."," ; F=fields:gmatch("(.-),")
values=values.."," ; V=values:gmatch("(.-),")
result={}
while true do
local k,v=F(),V()
if k==nil or v==nil then break end
result[k]=v
end
for k,v in pairs(result) do print(k,v) end
I am trying to group entries in a csv file into different tables in Lua, based on the last attribute. But for some reason the string comparison doesn't work. The following is the code:
trainer = {}
tester = {}
valer = {}
for line in io.lines(mlist) do
local split = {}
for token in string.gmatch(line, '([^,]+)') do
table.insert(split, token)
if token == 'val' then
print('heelo')
end
end
if split[5] == "val" then
print('hello world')
end
if split[5] == 'test' then
table.insert(tester, split[1])
elseif split[5] == 'train' then
table.insert(trainer, split[1])
elseif (split[5] == 'val') then
print('hello')
table.insert(valer, split[1])
end
end
The file mlist contains the following entries (It actually has a lot of records, but I am putting a few for testing):
050810,02747177,02747177,a2e9d8324c1f62cd5ecea499ceee624d,train
051087,02747177,02747177,89aff0d006fc22ff9405d3391cbdb79b,train
051145,02747177,02747177,c6ef918f335bb21c5896bab37ddebe7,train
051416,02747177,02747177,ec1c1aa7003cf68d49e6f7df978f3373,train
051506,02747177,02747177,a8b39c32604173c1d2b12aa6a0f050b3,train
051654,02747177,02747177,e3484284e1f301077d9a3c398c7b4709,train
001174,02747177,02747177,bf4dd114b53bd8f0d67352166d8df9fd,val
003009,02747177,02747177,2f1aed8925147120c62ac18334863d36,val
003735,02747177,02747177,c3b31dc8c48265ecfffc97a61124b1a9,val
004213,02747177,02747177,3a982b20a1c8ebf487b2ae2815c9,val
005241,02747177,02747177,91a4d060d380409c2056b4bd5d870b47,val
008467,02747177,02747177,4d6b6d392ec6b5b4c69692992c7aeb,val
008652,02747177,02747177,3be3e86b2fad511048d5a1386787189,val
008659,02747177,02747177,1e1015a06e43c0a5a44b6af22454453b,val
010510,02747177,02747177,62f4ed6e1df63042cecaed25e0da0964,val
013730,02747177,02747177,7069760a16db98f46c9e5b09a1c294d9,val
016657,02747177,02747177,ae3257e7e0dca9a4fc8569054682bff9,val
018178,02747177,02747177,86194a4645da1f19e14ca01ae177e9d,val
019142,02747177,02747177,e5b7b5112e396a49b581cc9c4410f841,val
021424,02747177,02747177,4088f2056763a95752e986a5f722a6f,val
022098,02747177,02747177,b77e94ab409def2b72745b90f9692729,val
022185,02747177,02747177,b51812771e42354f9996a93ae0c9395c,val
027358,02747177,02747177,5092afb4be0a2f89950ab3eaa7fe7772,val
028916,02747177,02747177,63adebf24a1de9ecf91cc5a18046145f,val
031579,02747177,02747177,1c3cf618a6790f1021c6005997c63924,val
032507,02747177,02747177,dc7ce614dc719649b394cfa64dfabe8e,val
034010,02747177,02747177,6a1b359efc20cd1aaec6ee5ba573fa6d,val
035290,02747177,02747177,c904d927672acd48ad8a0ee9b106700e,val
036604,02747177,02747177,f116f3c432856fccddd8899c86e55073,val
039697,02747177,02747177,c21d8f5641be31a285cac25b72167160,val
040234,02747177,02747177,330cdd681a0890b190fdbeabcd02777c,val
041653,02747177,02747177,b838c5bc5241a44bf2f2371022475a36,val
044825,02747177,02747177,af6fa396b2869446d4d8765e3910f617,val
046115,02747177,02747177,1cb574d3f22f63ebd493bfe20f94b6ab,val
046248,02747177,02747177,942887c8d668501681faebbdea6bd9be,val
046853,02747177,02747177,92fa62263ad30506d2b12aa6a0f050b3,val
046957,02747177,02747177,c77e8499be0ce1e04f3443b22038d340,val
048064,02747177,02747177,c18e807ff9858a51fb016d9401ff3e29,val
048971,02747177,02747177,18dbebd6527cffa254685f5f473de41f,val
051563,02747177,02747177,7c90fba6cd7f73871c1ef519b9196b63,val
I checked the type of split[5] and it is indeed string. I even tried
print(split[5] == 'val')
which prints false.
Thanks for the help!
There is a simpler (more generic) way of splitting your lines into buckets according to the last 'key', without using a series of if blocks to catch every possible 'key'. Something like this (use input redirection to load the file in this example):
local groups = {}
for line in io.lines() do
v,k = line:match '^(%d+),%d+,%d+,%x+,(%w+)$'
if v ~= nil and k ~= nil then -- or, just if k
local t = groups[k]
if t == nil then t = { v } else t[#t+1] = v end
groups[k] = t
end
end
-- And, to see table contents for verification...
for k,v in pairs(groups) do
print(k)
for i,v in ipairs(v) do print('',i,v) end
end
UPDATE/SOLUTION:
Thanks to the solution of Egor Skriptunoff in the comments, this has been solved. The problem is on Linux the CR and LF are interpreted differently, and I was indeed using a file made on Windows on Linux. So just ignoring the last character in every line solves it. According to Egor's solution modifying the inner for that is splitting with this works:
for token in line:gsub('\r', ''):gmatch('[^,]+') do
....
end
Thanks again to Egor for the solution and the explanation!