我想自动生成一个唯一的8-10个字符的ID字符串,其中包含某种校验和位,以防止数据录入时出现错字。我更喜欢没有连续数字的东西,数据输入人员会以“rut”结束,并习惯于一直输入相同的序列。
是否有与此类事情相关的最佳做法/陷阱?
更新:好的,我想我需要提供更多细节。
第二次更新好的,我不明白这有什么令人困惑,但我会尝试进一步解释。我正在尝试创建将在表单上创建的跟踪号码,这些号码将在以后填写并输入数据。我将生成id并将其打在表单上; id需要是唯一的,它需要支持很多数字,并且它需要合理地防止数据输入。
我不知道这是否已经完成,或者即使可以做到,但是问这个问题也没什么坏处。
答案 0 :(得分:4)
您可以模仿航空预订系统:他们使用A-Z和0-9作为字符将数字转换为base-36。因此它们的上限为36 ^ 6。
如果您需要保证唯一性,并且您不希望它们是连续的,那么您必须将使用过的随机数保存在某个表格中。
获得随机ID或伪随机ID后,您只需计算您的checkdigit。
Use a CRC algorithm.它们可以适应任何所需的长度(在您的情况下,6位)。
修改强>
如果不清楚:即使你使用alpha代码,你也必须在生成checkdigit之前把它变成一个数字。
修改强>
答案 1 :(得分:2)
大多数信用卡使用Luhn algorithm(也称为mod10算法)作为校验和算法来验证卡号。来自维基百科:
Luhn算法将检测任何单位错误,以及 几乎所有相邻数字的换位。但是,它不会 检测两位数序列09到90的转置(或反之 亦然)。
该算法是通用的,可以应用于任何识别号。
答案 2 :(得分:2)
你的问题很普遍 - 因此只是一些一般方面:
ID是否需要“不可饶恕”? 如果是的话,那么某种散列应该在混合中。
ID是否需要“安全”(例如激活密钥或其他内容)? 如果是,那么某种公钥加密应该是混合的。
ID /校验和计算需要快吗? 如果是,则可能需要一些非常简单的算法,如CRC32或Luhn(信用卡校验和算法)或soem条形码校验和算法。
ID生成是否集中? 如果没有,那么您可能需要查看GUID,当前时间,MAC地址和类似的东西。
更新 - 根据评论:
要检查输入的值,您只需从最后一位数字中重新计算CRC-6-ITU,然后将结果与最后一位数字进行比较。
上述内容相当“不可饶恕”,但绝对不是“高度安全”。
更新2 - 根据评论:
有关如何在javascript中计算CRC的一些灵感,请参阅this - 它包含CRC-8的javascript代码等。
您应该能够根据CRC-6-ITU多项式调整此代码。
答案 3 :(得分:1)
正如@BrokenGlass所说,你可以使用Luhn校验位算法。信用卡等使用Luhn算法 modulo 10. Luhn mod 10 计算从字母表中抽取的句子的校验位,仅由十进制数字组成(0-9 )。但是,它很容易适用于计算从任何大小的字母表中提取的句子的校验位(二进制,八进制,十六进制,字母数字等)
要做到这一点,您只需要两种方法和一种属性:
正在使用的字母表中的代码点数量。
这实际上是编号系统的 base 。例如,十六进制(基数为16)字母表由16个字符组成(忽略区分大小写的问题):'0123456789ABCDEF'。 '0' - '9'有其通常的含义; 'A' - 'F'是代表10-15的基数16位数。
将字符从使用中的字母转换为相应的代码点的方法。
例如,以十六进制表示,字符“0” - “9”代表代码点0-9;字符'A' - 'F'代表代码点10-15。
将代码点转换为相应字符的方法。
与上述相反。例如,在十六进制中,代码点12将转换为字符“C”。
如果字母表中不存在给定的代码点,您应该通过ArgumentException
。
维基百科的文章"Luhn mod N algorithm"在解释校验位的计算及其验证方面做得非常好。