How Can I Generate A Random Code?

I was wondering how I can generate a random code. For example, KFASjdaJASD8312.

I need this to protect my game from exploits. (So They Cannot Fire Remotes Without The Code)

Edit: My thought was creating 3 variables with tables and each time a random letter would get picked. Is this the best approach?

You could have a list of random codes in a metatable and use math.random to do this.

1 Like

Do you have any good tutorials on MetaTables?

Use GenerateGUID.

local HttpService = game:GetService("HttpService")
...
-- This creates a universally unique identifier string.
local newCode = HttpService:GenerateGUID(false)

3 Likes

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])
2 Likes

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

So there’s two things to unpack here:

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.

My example script would return a random number in between 1 - 3.

It would need to be:

math.randomseed(tick())
local MetaTable = {1, 2, 3}
local Key = math.random(1, #MetaTable)

Your example indexes the MetaTable with itself, which would throw an error as it’s not defined, and I’m unsure you can do cyclical references

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.

It would work with letters:

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 :slight_smile:

The issue with your initial code:

People can just intercept the firing of the RemoteEvent and change the arguments.

2 Likes

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))

This will not work, exploiters can just rip the code from your localscripts

You can’t know what the code is if a server script is generating it.

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.

Sidenote on why this isn’t completely useless

@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

image

Hope this helps. If you have any questions, feel free to ask.

6 Likes