65.9K
CodeProject 正在变化。 阅读更多。
Home

创建唯一的、可重现的用户 ID,无需 SSN

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.83/5 (4投票s)

2006年10月11日

2分钟阅读

viewsIcon

57674

downloadIcon

238

尝试解决创建包含 SSN 的用户 ID 的问题。

引言

我一直在寻找一种创建独特且易于记忆的用户 ID 的方法。我研究了许多算法,包括 HIPAA 提出的唯一健康标识符方案。不幸的是,我所研究的方案都涉及使用个人的社会安全号码。然而,大多数州政府不允许将社会安全号码用于此目的(但没有提供任何解决方案)。我的目标是基于个人的一些不太常改变的常见信息来创建用户 ID。该用户 ID 必须能够被重新创建(而不是随机生成),这样就不需要在数据库中存储它。

免责声明

以下代码和本文档附件并非用于生产环境,原样使用... 其中包含几个 MsgBox() 和调试语句,我在使用 30000 个用户的数据集进行测试时使用它们来查找重复项。我将此代码分享给社区,以征求建议并至少启动讨论,并希望获得更多关于如何始终保持其唯一性的想法。目前的代码,如果两个人拥有相同的名字(名和姓)并且出生在同一天(包括年份),他们将拥有相同的用户 ID。除此之外,我不确定如何测试重复项出现的频率。但如上所述,我使用大约 30000 人的数据进行了测试。

代码

其核心在于一个 CreateUserID 函数。该函数接受名、姓和出生日期作为参数... 进行一些计算,并输出一个假定的唯一 ID,格式为首字母、姓氏的前 4 个字母和一些数字。

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

我没有包含示例应用程序,因为它包含硬编码的个人信息列表。可供下载的类旨在逐个使用,或者您可以将其用于一次处理多个用户并返回一个 ArrayList。当然,您可以根据需要使用它。祝你好运,请告诉我您的想法!我绝对不是数学家,所以我预计会收到很多评论!

考虑因素

GUID - 是的,我考虑过这个,但它不允许我为相同的参数重复获得相同的结果。

使用 Base36 将数字缩短用户 ID - 考虑过这个,但会使用户更难记住。

使用社会安全号码的一部分 - 之前已经提到,使用社会安全号码是不可行的。

© . All rights reserved.