Conversion of sequence of bytes to ASCII string in lua - lua

I am trying to write custom dissector for Wireshark, which will change byte/hex output to ASCII string.
I was able to write the body of this dissector and it works. My only problem is conversion of this data to ASCII string.
Wireshark declares this data to be sequence of bytes.
To Lua the data type is userdata (tested using type(data)).
If I simply convert it to string using tostring(data) my dissector returns 24:50:48, which is the exact hex representation of bytes in an array.
Is there any way to directly convert this byte sequence to ascii, or can you help me convert this colon separated string to ascii string? I am totally new to Lua. I've tried something like split(tostring(data),":") but this returns Lua Error: attempt to call global 'split' (a nil value)
Using Jakuje's answer I was able to create something like this:
function isempty(s)
return s == nil or s == ''
end
data = "24:50:48:49:4A"
s = ""
for i in string.gmatch(data, "[^:]*") do
if not isempty( i ) then
print(string.char(tonumber(i,16)))
s = s .. string.char(tonumber(i,16))
end
end
print( s )
I am not sure if this is effective, but at least it works ;)

There is no such function as split in Lua (consulting reference manual is a good start). You should use probably string.gmatch function as described on wiki:
data = "24:50:48"
for i in string.gmatch(data, "[^:]*") do
print(i)
end
(live example)
Further you are searching for string.char function to convert bytes to ascii char.

You need to mark range of bytes in the buffer that you're interested in and convert it to the type you want:
data:range(offset, length):string()
-- or just call it, which works the same thanks to __call metamethod
data(offset, length):string()
See TvbRange description in https://wiki.wireshark.org/LuaAPI/Tvb for full list of available methods of converting buffer range data to different types.

Related

codeUnits property vs utf8.encode function in Dart

I have this little code:
void main(List<String> args) {
const data = 'amigo+/=:chesu';
var encoded = base64Encode(utf8.encode(data));
var encoded2 = base64Encode(data.codeUnits);
var decoded = utf8.decode(base64Decode(encoded));
var decoded2 = utf8.decode(base64Decode(encoded2));
print(encoded);
print(encoded2);
print(decoded);
print(decoded2);
}
The output is:
YW1pZ28rLz06Y2hlc3U=
YW1pZ28rLz06Y2hlc3U=
amigo+/=:chesu
amigo+/=:chesu
codeUnits property gives an unmodifiable list of the UTF-16 code units, is it OK to use utf8.decode function? or what function should be used for encoded2?
It's simply not a good idea to do base64Encode(data.codeUnits) because base64Encode encodes bytes, and data.codeUnits isn't necessarily bytes.
Here they are (because all the characters of the string have code points below 256, they are even ASCII.)
Using ut8.encode before base64Encode is good. It works for all strings.
The best way to convert from UTF-16 code units to a String is String.fromCharCodes.
Here you are using base64Encode(data.codeUnits) which only works if the data string contains only code units up to 255. So, if you assume that, then it means that decoding that can be done using either latin1.decode or String.fromCharCodes.
Using ascii.decode and utf8.decode also works if the string only contains ASCII (which it does here, but which isn't guaranteed by base64Encode succeeding).
In short, don't do base64Encode(data.codeUnits). Convert the string to bytes before doing base64Encode, then use the reverse conversion to convert bytes back to strings.
I tried this
print(utf8.decode('use âsmartâ symbols like â thisâ'.codeUnits));
and got this
use “smart” symbols like ‘ this’
The ” and ‘ are smart characters from iOS keyboard

calculating string length causes confustion

I am confused by the following output:
local a = "string"
print(a.len) -- function: 0xc8a8f0
print(a.len(a)) -- 6
print(len(a))
--[[
/home/pi/test/wxlua/wxLua/ZeroBraneStudio/bin/linux/armhf/lua: /home/pi/Desktop/untitled.lua:4: attempt to call global 'len' (a nil value)
stack traceback:
/home/pi/Desktop/untitled.lua:4: in main chunk
[C]: ?
]]
What is the proper way to calculate a string length in Lua?
Thank you in advance,
You can use:
a = "string"
string.len(a)
Or:
a = "string"
a:len()
Or:
a = "string"
#a
EDIT: your original code is not idiomatic but is also working
> a = "string"
> a.len
function: 0000000065ba16e0
> a.len(a)
6
The string a is linked to a table (named metatable) containing all the methods, including len.
A method is just a function, taking the string as the first parameter.
function a.len (string) .... end
You can call this function, a.len("test") just like a normal function. Lua has a special syntax to make it easier to write. You can use this special syntax and write a:len(), it will be equivalent to a.len(a).
print(a.len) -- function: 0xc8a8f0
This prints a string representation of a.len which is a function value. All strings share a common metatable.
From Lua 5.4 Reference Manual: 6.4 String Manipulation:
The string library provides all its functions inside the table string.
It also sets a metatable for strings where the __index field points to
the string table. Therefore, you can use the string functions in
object-oriented style. For instance, string.byte(s,i) can be written
as s:byte(i).
So given that a is a string value, a.len actually refers to string.len
For the same reason
print(a.len(a))
is equivalent to print(string.len(a)) or print(a:len()). This time you called the function with argument a instead of printing its string representation so you print its return value which is the length of string a.
print(len(a))
on the other hand causes an error because you attempt to call a global nil value. len does not exist in your script. It has never been defined and is hence nil. Calling nil values doesn't make sense so Lua raises an error.
According to Lua 5.4 Reference Manual: 3.4.7 Length Operator
The length of a string is its number of bytes. (That is the usual
meaning of string length when each character is one byte.)
You can also call print(#a) to print a's length.
The length operator was introduced in Lua 5.1,

send hex variable via TCP socket

Probably it's an easy thing, but I'm a Lua beginner...
I'm creating a very simple QSC QSYS plugin to control a projection server using KVL API. Server API is based on hex strings.
For example this command asks the server to load a the playlist with 9bf5455689ed4c019731c6dd3c071f0e uuid:
Controls["LoadSPL"].EventHandler = function()
sock:Write(
"\x06\x0e\x2b\x34\x02\x05\x01\x0a\x0e\x10\x01\x01\x01\x03\x09\x00\x83\x00\x00\x14\x00\x00\x00\x01\x9b\xf5\x45\x56\x89\xed\x4c\x01\x97\x31\xc6\xdd\x3c\x07\x1f\x0e"
)
end
Now I need to be able to create a string with a variable UUID, according to the text indicated in a textbox (or a list of available UUIDs read from the server) in the user interface.
I will concatenate this string to the fixed part of the command.
How can I correctly make a string like
ad17fc696b49454db17d593db3e553e5 become
\xad\x17\xfc\x69\x6b\x49\x45\x4d\xb1\x7d\x59\x3d\xb3\xe5\x53\xe5?
Try this:
local input = "ad17fc696b49454db17d593db3e553e5"
local output = input:gsub("%w%w", function(s) return string.char(tonumber(s, 16)) end)
Explanation: this takes every pair of characters, interprets them as base 16 numeric string, and then takes the character with that number, and uses that to replace the original characters.
EDIT: To make it clear what's going on, and why the other answers are wrong, backslash escape sequences like \xad are a feature of the Lua source code, in memory it's represented by a byte with value 173, just like A is represented by a byte with value 65. Trying to concatenate a literal backslash character with hexadecimal characters does not create an escape code. So the way to do that is manually with string.char.
#! /usr/bin/env lua
str = 'ad17fc696b49454db17d593db3e553e5'
strx = ''
for i = 1, #str, 2 do -- loop through every-other position in your string
chars = str :sub( i, i+1 ) -- capture every 2 chars
strx = strx ..'\\x' ..chars
end -- append a literal backslash, the letter x, then those 2 chars
target = [[\xad\x17\xfc\x69\x6b\x49\x45\x4d\xb1\x7d\x59\x3d\xb3\xe5\x53\xe5]]
print( x, x == target ) -- print results, and test if it meets expected target
\xad\x17\xfc\x69\x6b\x49\x45\x4d\xb1\x7d\x59\x3d\xb3\xe5\x53\xe5 true
This can be code-golfed into a one-liner
x=''for i=1,#s,2 do x=x..'\\x'..s:sub(i,i+1)end

Decrypt Lua byte code?

I'm encrypting my Lua code with this script.
local script = string.dump(
function()
local function h4x(strtbl)
buffer=""
for v in strtbl do
buffer=buffer..strtbl[v]
end
return buffer
end
print("encrypted")
end
)
buff=""
for v=1,string.len(script) do --Convert our string into a hex string.
buff=buff..'\\'..string.byte(script,v)
end
file=io.open('encrypted.txt','w') --Output our bytecode into ascii format to encrypted.txt
file:write(buff)
file:flush()
file:close()
The output of encrypted.txt is like "00/12/46/4/2/6/4/62/". How do I decrypt bytecode?
This text is not encrypted. It's just Lua bytecode in hexadecimal.
Discussion of means of disassembling this bytecode into human-readable opcodes is in another question: Lua equivalent to Python dis()?
Obviously its printing out each BYTE as a value (which is decimal, even though its stated its converted to hex) delimited by a '/'.
All you need to do then is fill an array using the bytes you pull from the string, using tonumber to convert them back to their byte value. this will help with parsing the formatted output

store string of bytes in table in lua

i need to store a string of bytes in a table in lua, how I can do it
thanks
Jp
Is that what you mean?
s="some string"
t={s:byte(1,#s)}
A Lua string is exactly what you wrote - a string of bytes. Lua is different from C-like languages in that it is 8-bit clean, meaning that you can even store embedded zero '\0' inside strings - the length of the string is held separately and is not based on where '\0' is.
You did not write where you want those bytes from (what is the source), so let's assume you are reading from a file. In the following example, f is a file handle obtained by calling io.open(filename), and t is a table (t = {}).
local str = f:read(100) -- will read up to 100 bytes from file handle f
t[#t + 1] = str -- will append the string to the end of table t
table.insert(t, str) -- alternative way of achieving the same

Resources