最近开发了几个 WinForm 的应用,但很多不讲武德;把程序复制分发到其他电脑上用又不打招呼。虽然对我没什么影响,但是如果是商业软件那就不好控制了;所以有点时间就写一个简单应用注册功能。本来计划是用非对称算法,就是根据秘钥进行计算,但这样需要一个注册器不方便。后来想了一下简单快捷的方法,就是MD5校验算了。
当应用程序启动,先访问有没有相关的INI文件,如果有就读取INI里面的设备号和日期值,再拼接成相关的字符串,MD5后匹配INI里面的秘钥;相同就表述已经注册了,不同则弹出注册提示。
string RUNDATE = ini.ReadString("Setup", "RUNDATE", "");注册日期
string KEYTEXT = ini.ReadString("Setup", "KEYTEXT", "");秘钥
string KEYNUM = ini.ReadString("Setup", "KEYNUM", "");设备号
if (string.IsNullOrEmpty(RUNDATE))
{
RUNDATE = DateTime.Now.ToString("yyyy-MM-dd");
ini.Write("Setup", "KEYNUM", SoftReg.GetMNum());
ini.Write("Setup", "RUNDATE", RUNDATE);
ini.UpdateFile();
}
if (KEYNUM != SoftReg.GetMNum()&& string.IsNullOrEmpty(KEYNUM))
{//判断设备码是否一致,不一致或为空则写入INI
KEYNUM = SoftReg.GetMNum();
ini.Write("Setup", "KEYNUM", KEYNUM);
ini.UpdateFile();
}
if (string.IsNullOrEmpty(KEYTEXT))
{
regpop W = new regpop();
W.ShowDialog();
}else{
string md5str = UserMd5("TGJ$" + KEYNUM + "$" + RUNDATE);
if (KEYTEXT != md5str)
{//匹配MD5是否相通
regpop W = new regpop();
W.ShowDialog();
}
}
static string UserMd5(string str)
{
string cl = str;
string pwd = "";
MD5 md5 = MD5.Create();//实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 0; i < s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
pwd = pwd + s[i].ToString("X");
}
return pwd;
}
class SoftReg
{
///<summary>
/// 获取硬盘卷标号
///</summary>
///<returns></returns>
public static string GetDiskVolumeSerialNumber()
{
ManagementClass mc = new ManagementClass("win32_NetworkAdapterConfiguration");
ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");
disk.Get();
return disk.GetPropertyValue("VolumeSerialNumber").ToString();
}
///<summary>
/// 获取CPU序列号
///</summary>
///<returns></returns>
public static string GetCpu()
{
string strCpu = null;
ManagementClass myCpu = new ManagementClass("win32_Processor");
ManagementObjectCollection myCpuCollection = myCpu.GetInstances();
foreach (ManagementObject myObject in myCpuCollection)
{
strCpu = myObject.Properties["Processorid"].Value.ToString();
}
return strCpu;
}
///<summary>
/// 生成机器码
///</summary>
///<returns></returns>
public static string GetMNum()
{
string strNum = GetCpu() + GetDiskVolumeSerialNumber();
string strMNum = strNum.Substring(0, 24); //截取前24位作为机器码
return strMNum;
}
public int[] intCode = new int[127]; //存储密钥
public char[] charCode = new char[25]; //存储ASCII码
public int[] intNumber = new int[25]; //存储ASCII码值
//初始化密钥
public void SetIntCode()
{
for (int i = 1; i < intCode.Length; i++)
{
intCode[i] = i % 9;
}
}
///<summary>
/// 生成注册码
///</summary>
///<returns></returns>
public string GetRNum()
{
SetIntCode();
string strMNum = GetMNum();
for (int i = 1; i < charCode.Length; i++) //存储机器码
{
charCode[i] = Convert.ToChar(strMNum.Substring(i - 1, 1));
}
for (int j = 1; j < intNumber.Length; j++) //改变ASCII码值
{
intNumber[j] = Convert.ToInt32(charCode[j]) + intCode[Convert.ToInt32(charCode[j])];
}
string strAsciiName = ""; //注册码
for (int k = 1; k < intNumber.Length; k++) //生成注册码
{
if ((intNumber[k] >= 48 && intNumber[k] <= 57) || (intNumber[k] >= 65 && intNumber[k]
<= 90) || (intNumber[k] >= 97 && intNumber[k] <= 122)) //判断如果在0-9、A-Z、a-z之间
{
strAsciiName += Convert.ToChar(intNumber[k]).ToString();
}
else if (intNumber[k] > 122) //判断如果大于z
{
strAsciiName += Convert.ToChar(intNumber[k] - 10).ToString();
}
else
{
strAsciiName += Convert.ToChar(intNumber[k] - 9).ToString();
}
}
return strAsciiName;
}
}
虽然这个并不是很完美,但应该是最简单的方法吧。后继可以加入例如日期匹配,当INI的日期与当前日期小于
多少天就是试用期到期。并且可以匹配设备的key是否同一台设备。目前我是通过CPU+硬盘来生成设备号,可以灵活变换也可以将MD5的字符变。万千变化吧。。。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。