Hello developers. I was recently looking into a jumble function I found on github but I have not been able to find out what this line does or how it works. Heres the line.
local str = tostring(int)
local letters = {}
for letter in str:gmatch'.[\128-\191]*' do
table.insert(letters, {letter = letter, rnd = math.random()})
end
At its simplest, .[\128-\191]*
will match a single character of any type followed by 0 or more of -
\128
and \191
(the latter three being in any quantity and any order)
\128 and \191 don’t have an ASCII representation, and I’m not sure what they’re doing there. Judging by the tostring, I would imagine that they’re some sort of invisible string modifier kind of like EoF. This doesn’t make a huge amount of sense though, and I’m going to assume that there might have been a better way to do whatever he was trying. Of course I could be wrong. You’re allowed to share offsite links here on the forum, can you please share the github link if you still have it, for curiosities’ sake?
Edit: I forgot how set matches use the - symbol. Best to just ignore all of this.
I use an offsite Lua pattern checker that helps in understanding patterns (there is the occasional discrepancy because Roblox lua is a bit altered from regular lua). This is a link to the pattern that you found. But as @JarodOfOrbiter said, it seems the pattern is a bit strange.
You could try printing the int
value that is passed as the argument to the function to see what the code tries to match it with.
Otherwise, some extra documentation on matching patterns can be found here on the devhub.
Searching the snippet seems like it might refer to randomly shuffling letters ? Nonetheless, the pattern itself is meant to match utf8 characters, and as such [\128-\191]*
is there so it can match multi-byte characters. Breaking it down, .
will match the first byte, and then subsequently [\128-\191]*
will match 0 or more preceding bytes. After the first byte, which can be from 0-127 or 194-244, preceding bytes will always range from 128 to 191.
local String = "©"
print(String:match("\194\169")) --- ©
---first byte is 194 second is 169
Instead of using '.[\128-\191]*'
though, one could also use the Utf8 library’s charpattern
constant which is just "[%z\x01-\x7F\xC2-\xF4][\x80-\xBF]*"
. If you were to convert those hex numbers to decimal you would find that the numbers are the same as what I mentioned above.
for letter in str:gmatch(utf8.charpattern) do
table.insert(letters, {letter = letter, rnd = math.random()})
end
3 Likes
local function jumbleInt(int)
math.randomseed(os.time())
local str = tostring(int)
local letters = {}
for letter in str:gmatch'.[\128-\191]*' do
table.insert(letters, {letter = letter, rnd = math.random()})
end
table.sort(letters, function(a, b) return a.rnd < b.rnd end)
for i, v in ipairs(letters) do letters[i] = v.letter end
return table.concat(letters)
end
Sorry I lost the github link but thats the full function