This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
neojames's profile picture

I'm Not Sure Of The Best Approach?

Started by neojames, 06 August 2013 - 05:57 PM
neojames #1
Posted 06 August 2013 - 07:57 PM
I'm trying to make a basic network authentication script (mostly for learning purposes) and I'm not sure of the best approach to storing the usernames and passwords. I want to store them in a separate machine-readable file (on a floppy disk so its a portable solution) which can then be read and used to authenticate against. I'm kinda planning on creating a script to write this file, so if its not human-readable that's not a problem.

Thanks for any help!
GamerNebulae #2
Posted 06 August 2013 - 08:03 PM
This goes beyond my league, but you want to have a look at the fs API. It's over on the wiki.I guess it involves making a new file on a disk and write specific names and passwords on that file?
neojames #3
Posted 06 August 2013 - 08:08 PM
I've got that far, I'm just not sure of the best format for the data. What I'd like (my background is in PHP & SQL, so I tend to think in those terms) is a table with Username and Password as the columns and then a kind of function to check those values against the table (so match username, lookup password, check password). However, I'm having trouble finding a way to save this table (although it may just be me being dense!) into a flatfile format which I can then restore.

It's really a shame there is no SQLite-style program for computercraft!
GamerNebulae #4
Posted 07 August 2013 - 06:52 AM
I've got that far, I'm just not sure of the best format for the data. What I'd like (my background is in PHP & SQL, so I tend to think in those terms) is a table with Username and Password as the columns and then a kind of function to check those values against the table (so match username, lookup password, check password). However, I'm having trouble finding a way to save this table (although it may just be me being dense!) into a flatfile format which I can then restore.

It's really a shame there is no SQLite-style program for computercraft!

I think, because you're storing strings, you should just write them on a file (in this case on a file on a disk) and later on go to a specific path and read it. You should put the passwords and usernames on a specific line in the file. Then you can pull stuff easily from the disk. One tip: If you make a program like that, be sure (if you have MiscPeripherals installed) to setup a Player Detector. That way the passwords are no use if you don't have the correct name.
Kingdaro #5
Posted 07 August 2013 - 01:30 PM
If you want to go the lazy route:

--# make our table of usernames and passwords
local users = {
  user1 = "pass";
  user2 = "pass";
}

--# save them to a file with textutils.serialize()
local file = fs.open('users', 'w')
file.write(textutils.serialize(users))
file.close()

--# load them using textutils.unserialize()
local file = fs.open('users', 'r')
local content = textutils.unserialize(file.readAll())
file.close()

--# make sure the user hasn't tampered with the file
--# if they have, the format will be screwed up, and content will be null
--# so we simply check if content exists
if content then
  users = content
end

textutils.serialize() is a function used to convert tables into strings, that are able to be loaded later using textutils.unserialize(). It stores them in a format like this:
{["user1"]="pass",["user2"]="pass",}
Which is only somewhat human-readable.

If you want to be really human-readable, that'll take a bit of effort with string matching and such.

--# using our "users" table defined in the previous example

--# keep a table of lines for use later
local lines = {}

--# go through all of the users, and add their username and password as a new line
for username, password in pairs(user) do
	--# \t is a tab character
	--# this looks pretty in text editors and that's pretty much it
	local line = username..'\t'..password

	--# add to the lines table
	table.insert(lines, line)
end

--# now we write all of the lines to our file.
local file = fs.open('users', 'w')
for i=1, #lines do
	file.writeLine(lines[i])
end
file.close()

--# for loading, we're going to read our file again, and store its contents in "content"
local file = fs.open('users', 'r')
local content = file.readAll()
file.close()

--# and of course empty our "users" table
users = {}

--# then use string matching to match every line.
--# the difference between gmatch and match, is that gmatch loops through every match found
--# and match only gives you one match.
for line in content:gmatch('[^\n]+') do --# matches "everything but a newline character"
	--# then the username and password
	local user, pass = line:match('(%S+)%s(%S+)') --# matches two groups of non-space characters sandwiching a space character. e.g. "(John) (Boehner)"

	--# after that, we just add the username and password to the table.
	users[user] = pass
end

The above example produces and reads a file format like this:

user1   pass
user2   pass

More on strings and string matching (you'll mainly want to look at "string.match", "string.gmatch", and "Patterns"): http://www.lua.org/manual/5.1/manual.html#5.4