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

string.byte/char

Started by BlueZero, 14 June 2013 - 03:37 AM
BlueZero #1
Posted 14 June 2013 - 05:37 AM
Trying to get this little ditty to work but I'm definitely doing it wrong. Hopefully someone'll be able to point me in the right direction but I can't seem to figure it out.


function enc()
	    userInput = io.read()
	    for i = 1, #userInput do
			    char = string.sub(userInput, i, i)
			    newChar = string.byte(char)
			    write(newChar)
	    end
	    return dec()
end

function dec()
	    decChar = string.char(newChar)
	    write(decChar.."\n")
end

enc()

Basically, it encodes the userinput, but it won't decode the userinput. I tried making it work within the loop but it seemed to pingpong back and forth encoding the decoding things individually.
Bomb Bloke #2
Posted 14 June 2013 - 06:04 AM
You need to store the "encoded" symbols somewhere if you want to refer to them later - you put them in "newChar", but you constantly overwrite that value, so at the end of your loop only the last character is stored. No, writing them to the screen doesn't count as "storing" them. ;)/>

Putting them in a table is the best way to go. This is generally always the case when dealing with an unpredictable amount of data that you want to keep stored for later reference.

Note also that the "dec()" function doesn't return anything in your code. Hence the "enc()" function can't return the result of the "dec()" function.

function enc(incomingText)
  local encodedStuff = {}  -- Declares a new table, which'll only be available inside this one function.

  for i = 1, #incomingText do
	encodedStuff[i] = string.sub(incomingText, i, i)   -- Put the current character in the table at position 'i'.
	-- table.insert(encodedStuff, string.sub(incomingText, i, i))  -- Another way to do the same thing... Sorta.
	print(encodedStuff[i])  -- Output what we put in the table to screen.
  end

  print("")   -- "print" automatically performs a line break at the end, unlike "write".
  return encodedStuff  -- Passes the contents of our table to the caller as a "result".
end

function dec(incomingBytes)  -- "incomingBytes" will be the table we got from the "enc()" function.
  local decodedStuff = ""  -- decodedStuff is local, so you can only access it in this function.

  for i = 1, #incomingBytes do
	decodedStuff = decodedStuff..string.char(incomingBytes[i])
	print(string.char(incomingBytes[i]))
  end

  print("")
  return decodedStuff  -- This returns the content of the variable as a result.
end

local userInput = io.read()		-- Do you mean just plain "read()"?
local encoded = enc(userInput)	 -- Pass the input to "enc()", put the results in "encoded"
local decoded = dec(encoded)	   -- Pass the encoded stuff to "dec()", put the result in "decoded"

print(decoded)

I haven't actually checked that the string manipulation functions do whatever is you want them to do, but this should give you a general understanding as to how you might go about doing things.
BlueZero #3
Posted 14 June 2013 - 06:12 AM
You need to store the "encoded" symbols somewhere if you want to refer to them later - you put them in "newChar", but you constantly overwrite that value, so at the end of your loop only the last character is stored. No, writing them to the screen doesn't count as "storing" them. ;)/>

Putting them in a table is the best way to go. This is generally always the case when dealing with an unpredictable amount of data that you want to keep stored for later reference.

Note also that the "dec()" function doesn't return anything in your code. Hence the "enc()" function can't return the result of the "dec()" function.

function enc(incomingText)
  local encodedStuff = {}  -- Declares a new table, which'll only be available inside this one function.

  for i = 1, #incomingText do
	encodedStuff[i] = string.sub(incomingText, i, i)   -- Put the current character in the table at position 'i'.
	-- table.insert(encodedStuff, string.sub(incomingText, i, i))  -- Another way to do the same thing... Sorta.
	print(encodedStuff[i])  -- Output what we put in the table to screen.
  end

  print("")   -- "print" automatically performs a line break at the end, unlike "write".
  return encodedStuff  -- Passes the contents of our table to the caller as a "result".
end

function dec(incomingBytes)  -- "incomingBytes" will be the table we got from the "enc()" function.
  local decodedStuff = ""  -- decodedStuff is local, so you can only access it in this function.

  for i = 1, #incomingBytes do
	decodedStuff = decodedStuff..string.char(incomingBytes[i])
	print(string.char(incomingBytes[i]))
  end

  print("")
  return decodedStuff  -- This returns the content of the variable as a result.
end

local userInput = io.read()		-- Do you mean just plain "read()"?
local encoded = enc(userInput)	 -- Pass the input to "enc()", put the results in "encoded"
local decoded = dec(encoded)	   -- Pass the encoded stuff to "dec()", put the result in "decoded"

print(decoded)

I haven't actually checked that the string manipulation functions do whatever is you want them to do, but this should give you a general understanding as to how you might go about doing things.

For the most part this works. Only thing Lua's saying is wrong is Line 18, stating "Number Expected, got string."
Bomb Bloke #4
Posted 14 June 2013 - 06:24 AM
Ah, right, change line 5 to:

encodedStuff[i] = string.byte( string.sub(incomingText, i, i) )

No real need to quote my whole long post, by the way. Certainly not if no one else has replied since I put it there. It's clear enough that you're replying to me. ;)/>
theoriginalbit #5
Posted 14 June 2013 - 06:28 AM
You need to store the "encoded" symbols somewhere if you want to refer to them later - you put them in "newChar", but you constantly overwrite that value, so at the end of your loop only the last character is stored.
OP, this is the exact same thing I was telling you about in the other thread with the `id` variable.

Btw, what are you actually using this for? Because I must say, if it is for security purposes it will definitely not do what you're hoping it to do!

And as for what Bomb Bloke just stated about not needing to quote his whole post, something I (and others) like to do is this

-snip-
that way you still get their attention but it is not a massive quote…
BlueZero #6
Posted 14 June 2013 - 06:29 AM
Ah, lol, sorry. And thanks man, this is cool. Works just how I wanted it to. Now I just gotta pick this apart and figure out how it all works then see if I can implement it.

Thanks again. :D/>

-snip-

ID Variable? Can't seem to remember that. Lol, not exactly running on full here so my apologies man. My learning curves are quite weird. Takes me a bit to understand a concept but once I got it, then I'm able to do a fair amount with it.
theoriginalbit #7
Posted 14 June 2013 - 06:32 AM
Works just how I wanted it to.
Which is exactly? All I see is a string being turned into a "stream" of their binary representation. Far from a secure encoding scheme, if that's what you're aiming for…
BlueZero #8
Posted 14 June 2013 - 06:37 AM
What I was doing was encoding text into something which will be apart of my project. It's a password encoding sort of thing but I'm not looking for it to be MD5 encoded or anything like that because that's a hell of a lot of stuff WAY over my head. Right now I'm just trying to create something that's not straight user readable, but able to be decoded and encoded easily.

Just as long as it isn't plain-text, then I'm satisfied with it.
theoriginalbit #9
Posted 14 June 2013 - 06:50 AM
I figured it would be for something like that.
To store something like a password you don't need to do any kind of encryption, since encryption is two way, and well, you just simply don't need that. The easiest/best solution is to use hashing. Hashing transforms your string into another, irreversible string. Hashing algorithms such as MD5 and SHA1 are really not that good to use as people have created methods of finding out what the password is based from massive lookup tables (called Rainbow Tables). As it stands the SHA2 family is the quickest hashing algorithm to use, but once again people have slowly started to build lookup tables. So using a method called Salting and Hashing you can attempt to get around this. A SALT is a random string of characters that is appended to the password (always in the same spot) before Hashing, to help remove the chance of a Rainbow Table attack. Then that password and salt is then stored to be later used for comparison. When the user inputs a password you then apply the salt, hash the password and compare against the database entry.
Now you did say that you didn't want to use an MD5 algo as it is way above your head, however luckily you would not need to implement the algorithms at all as two programmers on these forums have created, APIs to do a SHA-256 hashing for you.

SHA-256 hashing algorithm by GravityScore
SHA-256 hashing algorithm by KillaVanilla
BlueZero #10
Posted 14 June 2013 - 07:01 AM
-snip-

Ah, crap. I didn't know that. I was looking for MD5 and SHA hashing in native lua all over the place but could never find something that I could properly understand or use. I forgot to look here. That'll be a hell of a lot better then than what I was thinking of doing.
theoriginalbit #11
Posted 14 June 2013 - 07:04 AM
That'll be a hell of a lot better then than what I was thinking of doing.
Much better :)/>

When in doubt search the forums for things you want. The search algorithm isn't that great on these forums so using Google can help :)/>
computercraft.info:<search term here>
Check out my tutorial on searching google more efficiently if you need it. The tutorial can be found in the tutorials section of these forums.
BlueZero #12
Posted 14 June 2013 - 07:09 AM
-snip-

Lol, thanks again man. I'm gonna need to figure this out though. Or at least how to use it. My understanding of Lua is still on a very basic level.
theoriginalbit #13
Posted 14 June 2013 - 07:15 AM
If you use, lets say GravityScore's, and name the file `hash` then you would do this

local hashedString = hash.sha256( userInput )
and there you go, done.
Oh I just noticed in GravityScore's you will need to change line 186 to not have the `local` keyword or you will not be able to use it.

If you don't want to have it in an external file then you can put it in your code and all you need to do is

local hashedString = sha256( userInput )
and you don't need to remove the `local` in this instance either.
BlueZero #14
Posted 14 June 2013 - 07:53 AM
-snip-

Ah, that's cool. I think what I could do is implement something from one of my old project. Put this into my own personal pastebin and call on it externally. It'll be loaded into memory but not part of the actual script.

Still fuddling around with ideas. I don't know where I'm going to take this little project of mine, but happy to know one of the things I was hoping to implement is actually in existence.