Integer id's / GUIDs / byte arrays of any size can be reliable enough at practice, but they all do not correspond to the theoretical requirement (collisions happens), while valid theoretical solution exists and can be applied most of the time.
I'd formulate the solution as: in the equal-level system co-operation one's identity should be guaranteed by the system of a higher level. Higher-level system is the one which manages the lifetime of co-operating systems.
Example:
class John
{
private readonly int id;
public John(int id)
{
this.id = id;
}
public void UseSite(Site site)
{
site.CreateAccount(id, "john");
site.SetPassword(id, "john", "123");
/* ... */
}
}
class Site
{
public void CreateAccount(int humanId, string accName) { /* ... */ }
public void SetPassword(int humanId, string accName, string pwd) { /* ... */ }
/* ... */
}
class Program
{
static void Main(string[] args)
{
Site s = new Site();
// It's easy to guarantee the identity while there's only one object
John j = new John(4);
Console.ReadLine();
}
}
Program
is the higher-level module. It is responsible to use John
and Site
correctly. Providing John
with an unique identifier is a part of this responsibility.
You will find that it is impossible or very hard to deal with the identity of some real-life systems, like a human. It happens when these systems are on the same level as your system. Typical example is a human and a web-site. Your site will never have a guarantee that the right human requesting the page. In this case you should use the probability-based approach with a reliable hash.