出于好奇:序列号是如何生成的? 提示,算法?
我想知道序列号生成器和验证器是如何工作的。 我的目标是生成一个由五个部分组成的序列号,仅由数字和字母组成。
我喜欢编码作为一种爱好,不会称自己为专业程序员。 不过,我对这些有趣的功能如何在技术上发挥作用非常感兴趣,可以开阔我的思路。
任何提示、经验或书面算法都值得赞赏。
I wondering about how serial number generators and validator work. My aim would be to generate a serial number with five parts consisting of numbers and letters only.
I enjoy coding as a hobby and would not call myself a professional programmer. However, I am very interested in how those interesting functions work technically to broaden my mind.
Any hints, experiences or written algorithms are appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Brandon Staggs 写了一篇关于 实现部分序列号验证系统。 这些示例是用 Delphi 编写的,但可以转换为其他语言。
Brandon Staggs wrote a good article on Implementing a Partial Serial Number Verification System. The examples are written in Delphi, but could be converted to other languages.
为自己获取一个公钥/私钥对。 生成序列号 (10000, 20000, 30000, 40000, ....)具有某些识别特征(例如可被 10000 整除)。 使用您的私钥加密该号码。 使用一些人类可读的系统对该值进行编码(base 32 或 64)并将值分成几组,以便人们更容易解析。 每次销售您的应用程序时都会分发编码的序列号。
在应用程序的某个地方,您隐藏了公钥。 当用户输入编码序列号时,首先将其解码回二进制。 使用公钥对其进行解密。 检查它是否能被 10000 整除。
困难的部分在于实现 - 将公钥隐藏在应用程序中,使其不易被替换。 选择一些您可以轻松识别但又不会用完值的序列。 混淆应用程序,以便某人无法轻松跳过整个检查。 ETC...
Get yourself a public/private key pair. Generate sequence numbers (10000, 20000, 30000, 40000, ....) that have some identifying characteristic (e.g divisible by 10000). Encrypt that number using your private key. Encode that value using some human readable system (base 32 or 64) and separate the values into groups to make it easier for people to parse. Distribute the encoded serial number with each sale of you app.
Somewhere in the app, you have the public key hidden away. When a user enters an encoded serial number, first decode it back to binary. Use the public key to decrypt it. Check that it is divisible by 10000.
The hard part is in the implementation - hiding the public key in the app so that it can't be replaced easily. Choosing some sequence that you can identify easily, but not run out of values. Obfuscating the app so that someone can't easily skip past the whole check. etc...
嗯,传统上序列号是序列号。 所以第一个下线的例子有 sn 0001,然后下一个是 0002,下一个是 0003。我认为大多数人都能算出这个算法。
我认为您实际上是在询问产品密钥,它使用与公钥消息签名类似的机制 - 产品密钥是加密值,程序有一个公钥,允许它验证密钥是否有效,但只有软件供应商拥有“签署”产品密钥的密钥。 关于数字签名的维基百科文章具有一般机制; 唯一的条件是用户输入的密钥必须比 PGP 短很多。
如果您仅限于非常短的序列号,那么它不太可能足够大来存储典型签名机制的结果,在这种情况下,仅在其上使用某种校验和变体是很常见的。 其缺点是易于逆向工程 - 它的安全性是因为算法是“秘密的”,而不是由于任何加密属性。 每个产品都有自己的算法,而且它们通常很快就会被破解。
如果您有 5 个包含 5 个字符的块,则有 36^25 个组合,大于 2^128,因此可以使用生成 128 位的标准数字签名算法之一,然后将该值转换为基数 36。
Well, traditionally serial numbers are serial ... numbers. So the first example off the production line has sn 0001 then the next one is 0002 and the next one is 0003. I think that most people can work out that algorithm.
I think you're actually asking about product keys, which use a similar mechanism to public key message signing - the product key is the encrypted value, the program has a public key which allows it to verify that the key is valid, but only the software vendor has the secret key to 'sign' the product key. The wikipedia article on digital signatures has the general mechanism; the only proviso is that for a key to be entered by the user it has to be quite a bit shorter than a PGP one.
If you are restricted to a very short serial number, then it's unlikely to be big enough to store the result of a typical signing mechanism, in which case it's quite common to just use some variant of checksum on it. That has the disadvantage of being easy to reverse engineer - it's security is because the algorithm is 'secret' rather than due to any cryptographic properties. Each product would have its own algorithm, and they usually get cracked quite quickly.
If you have 5 blocks of 5 characters, you have 36^25 combinations, which is bigger than 2^128, so could use one of the standard digital signature algorithms which generates a 128 bit, then convert that value to base 36.
GUID(“全局唯一标识符”)可能是解决此问题的简单方法:
http://en.wikipedia .org/wiki/Globally_Unique_Identifier
GUID 包含 16 个字节,最常见的是以十六进制数字序列的文本形式编写,例如:
大多数编程语言应该能够使用可用库之一生成 GUID。
A GUID ("Globally Unique Identifier") could be an easy way to solve this:
http://en.wikipedia.org/wiki/Globally_Unique_Identifier
Guids contain 16 bytes and are most commonly written in text as a sequence of hexadecimal digits such as:
And most programming languages should be able to generate a GUID with one of the available libraries.
您可以使用随机数生成器并将输出存储在数据库中。
在激活请求的情况下,您只需检查序列号是否在数据库中并将序列号标记为“已使用”。
当然,这需要互联网连接,但有利于“购买一次,使用多次”的方法,并且在接到支持电话的情况下,您可以重新激活该序列以进行另一次重新安装。
稍后编辑:您还必须使用加密且经过身份验证的连接(例如 HTTPS 连接)进行互联网验证。
You can use a random number generator and store the outputs in a database.
In case of activation request, you just check if the serial is in the database and mark the serial as "used".
Of course, this needs an internet connection, but is good against "buy once, use many,many times" method and in case of support-call, you can reactivate that serial for another reinstall.
Later edit: You also must use for the internet verification an encrypted and authenticated connection, like a HTTPS one.
这里有很多信息:
http://en.wikipedia.org/wiki/Luhn_algorithm
http://en.wikipedia.org/wiki/Check_digit
Lots of info here:
http://en.wikipedia.org/wiki/Luhn_algorithm
http://en.wikipedia.org/wiki/Check_digit