Create a unique and reproducable user id without the use of SSN






2.83/5 (4 votes)
Oct 11, 2006
2 min read

57255

238
Attempts to solve the problem of creating userid's with SSN's
Introduction
I have been looking all over for a way to create a unique and memorable user id for some time. I looked at a lot of algorithms including HIPAA's proposal for a unique health identifier. Unfortunately, everything I looked at involved the use of a persons SSN in some way. Most state governments however disallow the use of SSN for this purpose (yet do not offer any solution). My goal here was to create a userid based on some not oftenly changed common information about a person. The userid had to be recreated (not random) so that it did not have to be stored in a database.
Disclaimer
The code below and attached to this article is not meant for production use as is... there are several MsgBox()
's and debug statements that I used while testing this against a 30000 userbase looking for duplicates. I'm throwing this out there to the community for suggestions and to at least start a discussion, and hopefully get some more ideas on how to always keep this unique. As it is written now, if you have the same name (first and last) and were born on the same day (including year) you would have the same userid. Besides that, I'm not sure how to test just how often you would get duplicates. But as I stated above, I tested this with an approximate 30000 people.
Code
The guts of this is in a CreateUserID function. The function takes first name, last name and date of birth as arguments... does some calculations and spits out a presumably unique ID in the form of first initial, first 4 of last name, and some digits.
Public Function CreateUserId(ByVal fName As String, ByVal lName As String, ByVal dob As Date) As String
StripFunnyCharacters(fName)
StripFunnyCharacters(lName)
If fName.Trim.Length = 0 Then Throw New ArgumentException("FirstName must be supplied")
Dim userName As String = ""
userName &= fName.Substring(0, 1)
userName &= lName.Substring(0, CInt(IIf(lName.Length < 4, lName.Length, 4)))
userName = userName.ToUpper
Dim concatName As String = (fName & lName).ToUpper
Dim dblA As Double = 1.0
Dim c As Char
For i As Integer = 0 To concatName.Length - 1
'If i Mod 2 = 0 Then 'uses every other (odd) characters: 1st, 3rd, 5th, 7th, 9th...
c = concatName.Chars(i)
If i Mod 2 = 0 Then 'every other multiply then divide (keeps number under max Integer)
dblA *= Asc(c)
Else
If dblA < 10000 Then dblA *= 10000
dblA = CInt((dblA / Asc(c)))
End If
'End If
Next
Dim intC5 As Integer = CInt(dblA + (dob.Month * dob.Day * dob.Year)) Mod 100000 ' makes it between 0 and 9999
If intC5 < 10000 Then intC5 += (dob.Year + 10000) 'handles if 0
If intC5.ToString.Length <> 5 Then MsgBox(intC5)
userName &= intC5.ToString
If CHECK_DIGIT Then userName &= CreateCheckDigit(intC5).ToString()
' Console.WriteLine(userName)
Try
If ol.ContainsKey(userName) Then
If fName & "," & lName & "," & dob.ToShortDateString = ol(userName).ToString Then
Debug.WriteLine("Found Identical person: " & ol(userName).ToString)
Else
Throw New ApplicationException("Uh oh, found a non unique: " & vbCrLf & userName & ": " & ol(userName).ToString & " already added" & vbCrLf & userName & ": " & fName & "," & lName & "," & dob.ToShortDateString & " attempted.")
End If
Else
ol.Add(userName, (fName & "," & lName & "," & dob.ToShortDateString))
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return userName
End Function
I did not include a sample application as it contained a hardcoded list of personal information. The class available for download above is meant to use on a one by one basis, or you can use it to do a bunch of users at once and return an arraylist. You can use it any way you want of course. Good luck, and let me know what you think! I am by far not a mathemetician, so I expect lots of comments!
Considerations
GUID - Yeah, I thought of this, but it would not allow me to get the same result over and over again for the same parameters
Base36 the digits to shorten the userID - thought of this, but it would make it a little more difficult for a user to remember
Use part of SSN - Well, I mentioned earlier, that using SSN was out of the question.