local HttpService = game:GetService("HttpService")
...
-- This creates a universally unique identifier string.
local newCode = HttpService:GenerateGUID(false)
You could use this or look at my very short tutorial.
Here is my tutorial.
--[[ Putting math.randomseed(tick()) make math.random even more random.
Make sure to put it at the very top. ]]--
math.randomseed(tick())
local MetaTable = {1, 2 ,3}
-- Every time this variable is defined it will do a random one.
local Key = math.random(1, #MetaTable[MetaTable])
This method of securing your remotes is easily bypassed and can be exploited because at some point you need to send the code to the client for them to send it back to the server. Exploiters can see all remote traffic passing in and out of their client so it is just a question of the exploiter finding the code somewhere on their client. Once the exploiter has the code they can easily fire any remote they want by just attaching the code they found as one of the arguments.
The best way of securing your remotes is by applying the appropriate server sided validations and checks, assuming that everything passed to the server has been tampered with. Lets say a player is requesting for their money to be increased you should do the appropriate checks to see if they are even allowed to increase their money before increasing their money.
As for your question it may be easier to generate a random number instead of a string of random letters and numbers because in this circumstance it wont make much difference whether it is a string or a number. You could use math.random() to do this. E.g: math.random(1000, 100000) will generate a random number between 1000 and 100000.
I havenât tested it but unless Iâm missing something this wonât work? Youâre getting the __len of the table âMetaTableâ while indexing itself in that table? Your table is just an array of numbers, this wouldnât work - itâll likely return âattempt to get len of nil valueâ as an error
This isnât good practice. To do this effectively, you need to generate the same sequence of random codes on the server and the client. This means that both the server and client need to store a state value. An exploit can easily get the state of your random function and bypass your security check.
Itâs useful for throwing off the generic exploiter that just knows how to run a script someone else wrote, but anyone worth their salt wonât be stopped by this if they really want to send remotes in your game.
This is even easier if the code is static and doesnât change while the game is running. Youâll want to check your RemoteEvents on the server and make sure the data theyâre receiving isnât some exploitersâ junk data.
This only works if the server is generating codes. If the client and server need to independently generate their codes, youâd want to use two Random objects initialized to the same value.
On the client:
local randomObj = Random.new(1234)
function sendRemote(...)
remoteEvent:FireServer(randomObj:NextInteger(), ...)
end
On the server:
local randoms = {}
local players = game:GetService("Players")
players.PlayerAdded:connect(function(player)
randoms[player] = Random.new(1234) --Same seed as on the client
end)
players.PlayerRemoving(function(player)
randoms[player] = nil --Cleanup
end)
remoteEvent.OnServerEvent:connect(function(player, key, ...)
local randomObj = randoms[player]
--Verify client key
if (randomObj == nil or randomObj:NextInteger() ~= key) then
player:Kick("Something went wrong!")
return
end
--Your server code here
end)
Once again, this is bad practice and you shouldnât be relying on this for security.
The numbers I put were just as an example he could put as many keys (Including letters and numbers.) as he wanted into the table and it would work. The way you did would only work with numbers and not a random passcode.
local hash = ('a,b,c,d,e,1,2,3,4,5'):split ','
local function generatePoorPassword(length)
local pw = ''
for i = 1, length do
math.randomseed(tick())
local k = math.random(1, #hash)
pw = pw .. hash[k]
end
return pw
end
print(
generatePoorPassword(5) --> 4d335
)
Iâm not trying to one up you btw, this is Scripting Support - weâre meant to work together to help the OP. Iâm just pointing out a flaw in the example so that the OP doesnât get confused further
Your way would work too Iâm just saying my way would generate a random number between 1 and the number of keys in the table and then it would index it to get a random key.
Exploiters can decompile LocalScriptsâ source into readable format and easily discover whatever key or keys youâre using, itâll only take a bit longer for them to âexploitâ.
Regardless, your best option would be to in some way sync a random identifier between the server and client and immediately change it each time you fire a remote, but this is still generally not a good idea to rely upon.
Several tutorials and resources exist on the internet to explain metatables.
I made this a while ago:
local function randomWord(len, unique)
if unique then len = math.clamp(len, 0, 26) end
local letters = {}
for byte = 97, 122 do
table.insert(letters, string.char(byte))
end
local str = ""
local count = 0
repeat
count = count + 1
local rand = Random.new():NextInteger(1, #letters)
if unique then
if not string.find(str, letters[rand]) then
str = str.. letters[rand]
end
else
str = str..letters[rand]
end
until #str == len
return str
end
print(randomWord(3, false))
Exploiters can see the arguments passed through RemoteEvent::FireServer so trying to secure the client like this is pointless. âPasswordingâ your remotes is security through obscurity which I argue is not true security.
The code is useless if the localscripts donât have them. And if localscripts can get them then an exploiter can get them. An exploiter can basically pretend to be a localscript.
@ScriptideALT@sjr04
An important point to make here: Itâs not completely useless. Adding a code where exploiters have to read a remote event requires more work. Inexperienced exploiters (which make up a good majority) wonât be able to bypass it. While it can be bypassed, it still is useful. It shouldnât be your main defense, but it can still be a good one.
A good analogy is itâs like a brick wall. With the right equipment, it can be broken. But, if you donât have the tools, itâs a good defense.
The code OP wants
Hereâs some simple code that should achieve what you want
local chars = "ABCEDFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwxyz1234567890"
--The characters that can be used in the code. You can add symbols too if you want.
local function getCode(length)
local code = ""
for i = 1, length do
local randNum = math.random(1, chars:len())
code = code .. chars:sub(randNum, randNum)
end
return code
end
print(getCode(5))
print(getCode(15))
print(getCode(3))
Example output
Hope this helps. If you have any questions, feel free to ask.