这篇文章主要介绍“C#序列号的设计不重复的实现方法是什么”,在日常操作中,相信很多人在C#序列号的设计不重复的实现方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#序列号的设计不重复的实现方法是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
序列号的设计
序列号作为软件使用授权方式之一,被广泛使用在应用软件方面。主要考虑到这几方面:1.对知识产权的保护,毕竟付出来脑力劳动和体力劳动。2.商业竞争中增加防守的能力,防止被竞争对手盗取。3.增强合同的执行效力,防止另一方由于各种原因破坏合作机制。
基于上述方面,从保护、防守思维模式角度考虑,增加序列号功能是有必要的。每个作者或公司设计序列号的方式不一样,就是因为不一样,所以才能达到我们增加该功能的效果。
序列号长度尽可能短
主要是从成本角度考虑的。例如用户现场需要一个正版软件的序列号,你把序列号信息通过什么方式传递给用户呢?假设我们用对称或非对称方式生成一个很长的序列号,如果口述告诉对方的话,那么对方肯定要用纸和笔进行记录,最后输入到软件后还不一定正确;如果把序列号以文件的方式通过网络传递给对方,那么需要占用网络资源,另外对方的电脑不一定有网络环境。不管如何,很长的序列号在生成和传递的过程中可能涉及到的成本包括:材料成本、流量成本、人力成本和时间成本等。
如果一个字符可以表达序列号所需要的完整信息,那么是最理想的。但是,这是理想状态,是不可能实现的,至少以我现在的能力是无法完成的。所以,要以最佳的长度表达出序列号的全部信息。
避免出现容易混淆的字符生成一个序列号发给了用户,这个序列号包括:数字0和字母O,数字1和字母l。难道让用户一遍一遍的试嘛,这样的用户体验太差了,虽然嘴上不说出来,至少感觉不太舒服。
设计的思想要看序列号要实现什么样的功能和具备什么属性。从功能角度考虑,包括:1.一个计算机一个序列号;2.尽管输入的条件都一样,每次生成的序列号都不一样;3.对使用的时限进行验证;4.序列号有注册时限,超过规定的使用时间,序列号作废,避免短时间多次注册。从属性角度考虑,包括:同样的计算机、同样的输入条件生成的序列号都不一样。
我们把上述因素考虑进去,序列号长度为25位字符,序列号生成格式和元素信息如下图:
X01-X05:为计算机的特征码,5位字符串,获得机器某个部件的ID,这个部件可能为CPU、网卡、硬盘等信息,把ID进行MD5加密后取前5个字符作为特征码,来实现一机一码。这种方式,特征码有可能有相同的情况,但是机率很小。
X06-X13:为生成序列号的日期,8位字符串,格式为:yyyyMMdd。与后边的使用时间限制配合使用,来验证软件的使用期限。
X14-X15:为注册时间限制,2位数字字符,从生成序列号日期算起,超过此注册时间限制,序列号将无法正常进行注册操作。
X16-X20:为使用时间限制,5位数字字符,与生成序列号日期配合使用来验证软件使用期限。
X21:为序列号的偏移量,1位字符,不管在什么场景下,每次生成序列号的偏移量都不一样。
X22-X25:为保留数据位,暂时不使用。自定义一个序列号字典信息,例如:_Dictionary ="JCB8EF2GH7K6MVP9QR3TXWY4",把容易混淆的字符去掉,这个可以自定义。序列号的每个部分都是通过随机生成的偏移量(X21),对字典进行位移,根据输入的数字信息对应字典的下标提取相应的字符作为序列号的一个字符。
生成序列号的大概过程:
在字典信息的长度范围内随机生成一个偏移量数字。
根据偏移量数字对字典进行左或右的循环移动。
根据输入的数字信息,例如:2015中的2,作为下标,从字典信息中提取出相应的字符。
反向解析大概过程类似,只需要根据X21字符,与字典的字符进行匹配,对应的下标作为偏移量,就可以反向解析出各项信息。
1.MD5操作类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public
class
Safety
{
public
static
string
MD5(
string
str)
{
string
strResult =
""
;
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte
[] bData = md5.ComputeHash(Encoding.Unicode.GetBytes(str));
for
(
int
i = 0; i < bData.Length; i++)
{
strResult = strResult + bData[i].ToString(
"X"
);
}
return
strResult;
}
}
|
2.注册信息类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public
class
RegInfo
{
public
RegInfo()
{
KeySn =
""
;
Date=DateTime.MinValue;
RegLimitDays = 0;
UseLimitDays = 0;
Offset = 0;
}
public
string
KeySn {
get
;
set
; }
public
DateTime Date {
get
;
set
; }
public
int
RegLimitDays {
get
;
set
; }
public
int
UseLimitDays {
get
;
set
; }
public
int
Offset {
get
;
set
; }
}
|
3.偏移操作类型:
1 2 3 4 5 | internal
enum
OffsetType
{
Left,
Right
}
|
4. 序列号管理类
+ View Code
从安全角度来讲,.NET程序如果不加混淆的话,很容易被反编译出源代码的。从专业角度来讲,即使增加了序列号功能,也无济于事,专业的人员分分钟可以破解掉,尽管这样干的人很少,但是存在这种可能性。如果一个软件人员想了解一个很好的软件,第一反映可能就是反编译。
对于公司或商业使用的软件来讲,增加混淆还是有必要的,尽管现在开源很流行。
不管.NET程序如何进行混淆,理论上都是可以破解的,理论的东西就不赘述了。通常接触过的破解方式有两种:注册机方式和暴力方式。
注册机的方式,需要通过软件的验证序列号的过程和机制反向推算出序列号的生成算法,根据反推的算法开发一个小软件,用于生成脱离作者授权生成序列号。这种方式不会破坏程序本身的代码,相对温和。暴力的方式,就是找到序列号验证部分的代码,通过删除或绕过验证代码等方式不让代码有效执行。这种方式会对程序本身的代码进行改动,所以也存在一些风险。
实现序列号有多种方式,上述方式不一定最好,但是希望对开发者有一定帮助。
最终实现效果图如下:
到此,关于“C#序列号的设计不重复的实现方法是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。