This post is meant as an informative post to spread more awareness regarding the Player:UniqueID function.
Essentially what Player:UniqueID does is:
util.CRC("gm_"..Player:SteamID().."_gm")
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
end
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)
end