0

Well, I've been doing so many things, when I was bored of course

So I want:

My code:

local abs, log, floor, insert, concat, format = math.abs, math.log, math.floor, table.insert,      table.concat, string.format
 function ToBinary(str)
     log2, _result = log(2), {} 
     for k = 1, #str do 
         n, t, m = str:byte(k), {}, 0 
         m = log(n) / log2
         if n < 0 then 
             m = m + 1 n = 2 ^ m - abs(n)     
         end
         for e = floor(m + 1), 0, -1 do
             t[#t + 1] = floor(n / 2 ^ e)
             n = n % 2 ^ e
         end 
         insert(_result, #concat(t) == 7 and format('0%s',concat(t)) or concat(t))
     end
     return concat(_result,'\32')
 end
 function FromBinary(str)
     str, _result = str:gsub('\32',''),{''}
     for k = 1, #str, 8 do 
         local byte = str:sub(k, k + 7)
         assert(tonumber(byte,2), 'Malformed binary sequence, got: ' .. str:sub(k, #str))
         insert(_result,string.char(tonumber(byte,2)))
     end 
     return concat(_result)
 end 

The problem is that it works well, but when the character is over or under 8 symbols in binary code, it just wont decode the binary code, I'm talking about the unicode characters, tho I tried like detecting it and yea maybe someone will say just split the spaces but what if it has no spaces, and even ur eyes cant look into that and say, its 9 bytes or 7.

I hope there's someone who will understand me.

frogl8
  • 19
  • 3
  • I'm a bit confused on what you want to achieve, maybe include a few examples. – Luke100000 Aug 18 '23 at 07:22
  • The script has function FromBinary which should decode the binary code to text, but the problem is when in the text theres a unicode character that has more than 1 byte and 8 bits or under 8 bits, it wont detect it, thats because it checks for every 8 symbols, its possible to detect all the spaces and split them which will fix this problem, but when it has no spaces its not. Thats what I'm trying to achieve. – frogl8 Aug 18 '23 at 07:45
  • "Binary code" is quite vague, everything is binary here. Unicode itself has no bytes or bits so I assume you want to parse UTF-8 or similar? Then please, use a library, thats not something one should do themselve: https://q-syshelp.qsc.com/Content/Control_Scripting/Lua_5.3_Reference_Manual/Standard_Libraries/4_-_Basic_UTF-8_Support.htm – Luke100000 Aug 18 '23 at 08:04

2 Answers2

0

Your solution seems to be little bit overcomplicated. You can just loop thru every character and for every character go thru all bits in reversed order, get whatever there is 0 or 1 (using modulo), save this to table and then bit shift right (or floor /2, if you don't have bitshift library), then just continue your logic.

local floor, insert, concat = math.floor, table.insert, table.concat
function ToBinary(str)
    local _result = {}
    for k = 1, #str do
        local n, t = str:byte(k), {}
        for i = 8, 1, -1 do
            t[i] = n % 2
            n = floor(n / 2)
        end
        insert(_result, concat(t))
    end
    return concat(_result,' ')
end

There are also other solutions, see for example here.

Side note: do not use globals in functions, if it is not needed. You cache functions like math.floor, which is OK, but in functions, use locals also, mainly for variables, that are frequently accessed.

Aiq0
  • 306
  • 1
  • 11
  • This is all cool, but I need to decode the binary has unicode characters and over 8 bytes per character, and no spaces – frogl8 Aug 17 '23 at 19:28
  • You mean that Unicode characters having more than 8 *bits* should not be separated by spaces? – Aiq0 Aug 17 '23 at 19:55
  • No I mean when unicode character have more than 8 bits or under that, it cant be detected by FromBinary function since it detects every 8 symbols, if the code has no spaces like 011000010110001001100011 u just cant detect it, so I'm asking – frogl8 Aug 18 '23 at 07:42
  • Unicode characters are constructed of 1 or more bytes (so it is always multiple of 8 bits), so you can just go byte by byte and convert it to binary, same applies in reverse. Problem is, I think, with your ToBinary function, as it sometimes returns 9 or 7 bits. Try to give example input and output that you want. – Aiq0 Aug 19 '23 at 09:14
0

would this solve your problem?

function frombinary(binary)
    local split, result = binary:split(' '), {}
    for i = 1, #split do
        local char, value = split[i]:reverse(), 0
        for k = 1, #char do
            value = value + (tonumber(char:sub(k, k)) * (2 ^ (k - 1)))
        end
        result[i] = string.char(value)
    end
    return table.concat(result)
end

Updated:

this one only works with no spaces and perfect binary

function frombinary(binary)
    local result = {}
    for i = 1, (#binary / 8) do
        local chunk = binary:sub((8 * i) - 7 , 8 * i):reverse()
        local value = 0
        for k = 1, #chunk do
            value = value + (tonumber(chunk:sub(k, k)) * (2 ^ (k - 1)))
        end
        result[i] = string.char(value)
    end
    return table.concat(result)
end
  • this WILL solve my problem but just exactly as i said: "tho I tried like detecting it and yea maybe someone will say just split the spaces but what if it has no spaces, and even ur eyes cant look into that and say, its 9 bytes or 7." – frogl8 Aug 18 '23 at 18:43
  • bro i just told u that my code will do absolutely the same shit just when the byte is over 8 bits or under 8 bits and the code has no spaces u just cant detect it or u can idk thats what im trying to find out – frogl8 Aug 18 '23 at 22:10
  • 1
    so are you trying to detect spaces or convert binary that's under 8 bits to text – Red Crewmate Aug 19 '23 at 02:58