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

ASCII to Binary Converter

Started by Dragon53535, 27 July 2014 - 10:00 PM
Dragon53535 #1
Posted 28 July 2014 - 12:00 AM
ASCII to Binary Converter

And back again.



Have you ever wanted to convert your text into binary, or even convert your text from binary? Well then here you go!
This program can convert a string of text into a string of binary and can reverse the process!
To get the file you can type: "pastebin get LkFYQPGP ascii" into your computer and it willl work.

Syntax:

ascii.toBinary(stringoftext)
ascii.fromBinary(stringofbinary)

You can find the program Here.

If you want to use it in your program go right ahead, no permission needed.
Edited on 08 August 2014 - 08:32 PM
Dragon53535 #2
Posted 08 August 2014 - 10:31 PM
Yay it's an API now and you can convert to and from binary!
columna1 #3
Posted 19 August 2014 - 06:14 AM
This is nice for a start. Take a look into the functions 'string.byte' and 'string.char' and look into number to binary conversion functions. That way you can convert back an forth without that big table.
theoriginalbit #4
Posted 19 August 2014 - 09:17 AM
more precisely take a look into tonumber and how you can provide a base for it. it would reduce your fromBinary function to a single line.
Dragon53535 #5
Posted 19 August 2014 - 07:19 PM
This is nice for a start. Take a look into the functions 'string.byte' and 'string.char' and look into number to binary conversion functions. That way you can convert back an forth without that big table.
string.byte automatically converts the number into a base 10 representation of the binary number, and it would require a number to binary converter as you said.

more precisely take a look into tonumber and how you can provide a base for it. it would reduce your fromBinary function to a single line.
I can see that line, return string.char(tonumber(input,2)) however that would still require acutually me calling the toTable function first, and then converting it inside the toTable and just returning the same value string.concat'd so in essence i would really just have to return toTable(string,8) and then it would be fine.
Edited on 19 August 2014 - 05:20 PM
Dragon53535 #6
Posted 20 August 2014 - 09:32 AM
There we go, i updated the pastebin by writing the code from scratch and testing on my computer, and now the code is 92 lines as opposed to 56 and is 2941 characters shorter. All in all the code is cleaner and more effecient, and works by using string.byte, and string.char as suggested by theoriginalbit and columna1.

PS. the code converts base to binary with if statements checking if the string.byte number subtracted by the numerical value of the binary digit is greater than or equal to zero. Also i wrote the entire code on my ipad :P/>
Edited on 20 August 2014 - 07:35 AM
theoriginalbit #7
Posted 20 August 2014 - 11:27 AM
I can see that line, return string.char(tonumber(input,2)) however that would still require acutually me calling the toTable function first, and then converting it inside the toTable and just returning the same value string.concat'd so in essence i would really just have to return toTable(string,8) and then it would be fine.
Actually if you want to do entire strings it would be longer than a line… Example expanded for readability.

function fromBinary( str )
  assert( #str % 8 == 0, "malformed binary sequence" )
  local out = ""
  for i = 1, #str, 8 do
    local byte = str:sub(i, i + 8)
    local char = tonumber(byte, 2)
    out = out..string.char(char)
  end
  return out
end
Dragon53535 #8
Posted 20 August 2014 - 07:42 PM
I actually do the conversion fully in my toTable function, however what you posted is going to let me do it better. Quick question though, using assert would that exit the program entirely?
Edited on 20 August 2014 - 05:43 PM
theoriginalbit #9
Posted 21 August 2014 - 12:41 AM
Yes, assert is like a simplified version of

if not condition then
  error("message")
end
On that note, since this is an API you could do the following

if #str % 8 ~= 0 then
  error("malformed binary sequence", 2)
end
Having the 2 means that it blames the invoking function instead of your own.
Edited on 20 August 2014 - 10:43 PM
Dragon53535 #10
Posted 21 August 2014 - 09:19 AM
I implemented your changes so that it errors cleanly to the program calling it.
columna1 #11
Posted 22 August 2014 - 05:40 AM
I like the function you created to convert numbers to binary, very creative. However there are functions that do this quite well and (just as a tip) you would do well to learn some in order to cut down lines and add flexibility. Here is one I found that I used in a serial data transmission over redstone program a while back.

digits = {}
for i=0,9 do digits[i] = strchar(strbyte('0')+i) end
for i=10,36 do digits[i] = strchar(strbyte('A')+i-10) end
function numberstring(number, base)
   local s = ""
   repeat
	  local remainder = mod(number,base)
	  s = digits[remainder]..s
	  number = (number-remainder)/base
   until number==0
   return s
end
This will convert to many bases and is used like numberstring(10,2) which will output "1010" which if needed you can append the needed ammount of 0s onto the end like so

str = numberstring(10,2)
str = string.repeat("0",8-#str)..str
--this would return "00001010"


--you can also build this into the function itself like so:
return string.repeat("0",8#s)..s
You can also adapt the function to output a table but I think ill leave that to you :P/>
or you even use a loop and string.sub() with tonumber() to convert the string to the table format you used

hint:
Spoiler

for i = 1,#str do
  table.insert(table,tonumber(str:sub(i,i)))
end
Remember these are just suggestions and you don't have to implement them if you don't want. ;)/>
I like to learn new things so I gave you this, so have fun so please feel free to play around and edit it as you please!
theoriginalbit #12
Posted 22 August 2014 - 06:10 AM

str = numberstring(10,2)
str = string.repeat("0",8-#str)..str
--this would return "00001010"
--you can also build this into the function itself like so:
return string.repeat("0",8#s)..s
alternatively, using some Lua magic we can do this

str = string.format("%08d", numberString(10,2))
--# other examples
print(string.format("%08d", "01010")) --# outputs as 00001010
print(string.format("%08d", "11")) --# outputs as 00000011
print(string.format("%08d", "11000011")) --# outputs as 11000011
print(string.format("%08d", "100101101")) --# outputs as 100101101
the magic here is that even though %d specifies number, Lua is able to treat the string as a number as it only contains numbers.
Edited on 22 August 2014 - 04:11 AM
Dragon53535 #13
Posted 22 August 2014 - 11:56 PM
–snip–
Actually if you want to do entire strings it would be longer than a line… Example expanded for readability.

function fromBinary( str )
  assert( #str % 8 == 0, "malformed binary sequence" )
  local out = ""
  for i = 1, #str, 8 do
	local byte = str:sub(i, i + 8)
	local char = tonumber(byte, 2)
	out = out..string.char(char)
  end
  return out
end
Your code here is wrong and gave me some trouble :P/> it should have local byte = str:sub(i,i + 7) since i already equals the first number, and you need 1-8 not 1-9

I like the function you created to convert numbers to binary, very creative. However there are functions that do this quite well and (just as a tip) you would do well to learn some in order to cut down lines and add flexibility. Here is one:

digits = {} --# Note from Dragon: These three lines are useless as i can just set s to be remainder..s and have it work for binary, other bases, not so much, but i'm using it for binary.
for i=0,9 do digits[i] = strchar(strbyte('0')+i) end
for i=10,36 do digits[i] = strchar(strbyte('A')+i-10) end
function numberstring(number, base)
   local s = ""
   repeat
	  local remainder = mod(number,base)
	  s = digits[remainder]..s
	  number = (number-remainder)/base
   until number==0
   return s
end
This will convert to many bases and is used like numberstring(10,2) which will output "1010" which if needed you can append the needed ammount of 0s onto the end like so

str = numberstring(10,2)
str = string.repeat("0",8-#str)..str
--this would return "00001010"


--you can also build this into the function itself like so:
return string.repeat("0",8#s)..s
Remember these are just suggestions and you don't have to implement them if you don't want. ;)/>
I like to learn new things so I gave you this, so have fun so please feel free to play around and edit it as you please!
I had trouble doing string.repeat as that doesn't seem to be an actual function that i can use. Also strchar and strbyte needed to be string.char and string.byte, i'm guessing you didn't care to fix it, and assumed i would fix it :P/> Also mod isn't a function either, it is however an operator using % so that should be number % base. The rest worked amazingly :P/> thank you for your help there, time to mess around :P/>

-snip-
alternatively, using some Lua magic we can do this

str = string.format("%08d", numberString(10,2))
--snip--
the magic here is that even though %d specifies number, Lua is able to treat the string as a number as it only contains numbers.

Your code here worked fabulously for using his numberstring function :D/> I thank you both for your help and showing me some new things that i can attempt to use on the project i'm working on (its a secret :P/>)
Edited on 22 August 2014 - 10:19 PM
Dragon53535 #14
Posted 23 August 2014 - 12:23 AM
I updated the pastebin code using more suggestions from columna and theoriginalbit which over halved my code. The code should be more efficient with larger numbers. The code, with their bits put in, and me figuring out i was using it inefficiently is now 707 chars and 29 lines.

Edit: Improving more, it's now 639 characters :P/>
Edited on 22 August 2014 - 10:58 PM