【问题标题】:Generate unique public user identifier with check digit生成带有校验位的唯一公共用户标识符
【发布时间】:2019-11-12 07:52:15
【问题描述】:

我们将患者和护理提供者的记录存储在我们的数据库中。我们需要为每个用户唯一识别他们的某种公共标识符,并使用某种校验位来最大程度地减少错误输入的机会。

在我的研究中,我发现了用于信用卡号码的 Luhn 算法;和一些变种。

但我想知道是否还有其他替代方案,可能更短的标识符或包含字母数字字符,可能更适合与公共用户标识符一起使用?

或者将信用卡号格式也用于用户标识符是否是一个有效的选择?

【问题讨论】:

  • 十六进制标识符可能会让事情变得更容易?
  • 如果您不想使用 GUID 或自动递增的数字,这对您有帮助吗? Unique random string generation
  • 这能回答你的问题吗? How to generate a verification code/number?
  • 谢谢大家,我已经根据你们的cmets回答了我自己的问题。
  • 首先,您希望有多少患者?意思是,您需要的唯一标识符的最大数量是多少?

标签: c# algorithm luhn


【解决方案1】:

基于cmets,我得出以下解决方案。

首先,我按照 nathanchere 在this SO thread 中的描述呈现一个 8 个字符的 LUID。

public class LUID
{
    private static readonly RNGCryptoServiceProvider RandomGenerator 
               = new RNGCryptoServiceProvider();
    private static readonly char[] ValidCharacters = 
               "ABCDEFGHJKLMNPQRSTUVWXYZ23456789".ToCharArray();
    public const int DefaultLength = 6;
    private static int counter = 0;

    public static string Generate(int length = DefaultLength)
    {
        var randomData = new byte[length];
        RandomGenerator.GetNonZeroBytes(randomData);

        var result = new StringBuilder(DefaultLength);
        foreach (var value in randomData)
        {
            counter = (counter + value) % (ValidCharacters.Length - 1);
            result.Append(ValidCharacters[counter]);
        }
        return result.ToString();
    }
}

然后我附加一个使用 iso7064 MOD 1271,36 标准计算的校验位,如here 所述。

我还添加了一个小检查,如果计算出的校验位包含 O、0、I 或 1,我会再次重新生成代码,直到不再包含这些字符。

结果是一个类似 6VXA35YDCE 的代码,它是相当独特的(如果我的数学是正确的,应该有 1.099.511.627.776 种可能的组合)。它也不包含I、1、O和0;避免混淆。

此外,在我使用它创建新用户之前,我确保数据库中尚不存在任何生成的 LUID,以确保它在发生冲突时继续工作。

我认为这符合我正在寻找的要求...

【讨论】:

  • 很高兴看到 LUID 很有帮助 :) 我也很想看看您是如何添加校验和的。我为以前的客户做了类似的事情,但使用严格的数字校验和数字,所以删除 1/0 并不重要(如果需要手动输入,很容易将最后一个数字强制为数字或转换 O->0 和I->1 以适应用例)并且不需要重复传递来避免这些数字。
  • 我提取该示例时也忽略了一些内容,如果您没有实现自动化测试等的ILUID 接口,该类可能应该是static
  • @nathanchere 对于校验位,我使用了archive.codeplex.com/?p=iso7064 的实现。它具有所有 ISO 7064 校验位算法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多