生成带有校验位的唯一 public 用户标识符
Generate unique public user identifier with check digit
我们将患者和护理提供者的记录存储在我们的数据库中。我们需要某种 public 标识符 为每个用户 唯一地 标识他们,并使用某种校验位来最小化机会错误的输入。
在我的研究中,我发现了用于信用卡号码的 Luhn 算法;和一些变体。
但我想知道是否还有其他替代方案,可能具有更短的标识符或也包含字母数字字符,可能更适合与 public 用户标识符一起使用?
或者将信用卡号格式也用于用户标识符也是一个有效的选择吗?
根据评论,我得出以下解决方案。
首先,我渲染了一个 8 个字符的 LUID,如 nathanchere 在 this SO thread 中所描述的那样。
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();
}
}
然后我按照 here.
的描述附加一个用 iso7064 MOD 1271,36 标准计算的校验位
我还添加了一个小检查,如果计算出的校验位包含 O、0、I 或 1,我会再次重新生成代码,直到它不再包含这些字符为止。
结果是类似于 6VXA35YDCE 的代码,它非常独特(如果我的数学是正确的,应该有 1.099.511.627.776 种可能的组合)。它也不包含I、1、O和0;以免混淆。
此外,在我使用它创建新用户之前,我确保数据库中不存在任何生成的 LUID,以确保它在发生冲突时继续工作。
我认为这符合我一直在寻找的要求...
我们将患者和护理提供者的记录存储在我们的数据库中。我们需要某种 public 标识符 为每个用户 唯一地 标识他们,并使用某种校验位来最小化机会错误的输入。
在我的研究中,我发现了用于信用卡号码的 Luhn 算法;和一些变体。
但我想知道是否还有其他替代方案,可能具有更短的标识符或也包含字母数字字符,可能更适合与 public 用户标识符一起使用?
或者将信用卡号格式也用于用户标识符也是一个有效的选择吗?
根据评论,我得出以下解决方案。
首先,我渲染了一个 8 个字符的 LUID,如 nathanchere 在 this SO thread 中所描述的那样。
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();
}
}
然后我按照 here.
的描述附加一个用 iso7064 MOD 1271,36 标准计算的校验位我还添加了一个小检查,如果计算出的校验位包含 O、0、I 或 1,我会再次重新生成代码,直到它不再包含这些字符为止。
结果是类似于 6VXA35YDCE 的代码,它非常独特(如果我的数学是正确的,应该有 1.099.511.627.776 种可能的组合)。它也不包含I、1、O和0;以免混淆。
此外,在我使用它创建新用户之前,我确保数据库中不存在任何生成的 LUID,以确保它在发生冲突时继续工作。
我认为这符合我一直在寻找的要求...