Why you should not use UniqueID

This post is meant as an informative post to spread more awareness regarding the Player:UniqueID function.

Essentially what Player:UniqueID does is:


I’ve always known this had potential to produce checksums that are not unique to the user, I was however not aware of the extent of how many SteamIDs are affected.

I’ve found several SteamIDs that are affected, I did not go through nearly all known SteamIDs, only about 20 million, but the result was enough for me to make this post.
The following gives an idea of the extent of the non-uniqueness:

My conclusion is to discourage coders from using UniqueID as a unique identifier for players, such as in databases.

I’ll include the alternative I went for on my server below to have fairly short numbers uniquely identify users:

	local plyMeta = FindMetaTable("Player")
	function plyMeta:ID3()
		if !IsValid(self) then return 0 end -- Not sure if an IsValid check is needed here, better safe than sorry
		if self:IsBot() then return -1 end -- Return -1 to indicate bot while still returning a number
		local sid = self:SteamID()
		local a = tonumber(string.sub(sid, 9, 9))
		local b = tonumber(string.sub(sid, 11))

		if !isnumber(a) or !isnumber(b) then return 0 end

		return b*2+a

	function util.SteamIDFromID3(id3)
		id3 = tonumber(id3) -- Just incase it is passed as a string
		if !isnumber(id3) then return end
		if (id3 == -1) then return "BOT" end
		local a = id3%2
		local b = math.floor(id3/2)
		return string.format("STEAM_0:%s:%s", a, b)

you can use this and a script to create a jsonfile to convert to possible steamids. It’s opencl so it will use your gpu for the speed.

We’ve also had multiple discussions about this, even recently on the next update thread.

why can’t we all just use ply:SteamID64()

Even DarkRP recently switched to SteamID64. :smile:

It carries extra useless numbers.