首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网页制作-> Discuz!专栏
注册机制_delphi教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 

现在,我有时间去关注软件盗版问题,我将描述一下我的注册方法,希望对你有所帮助。

几年以来,我有过许多的方案,有的简单,有的复杂,其目的都是为了防止软件的非法使用。这些方法包括两种:硬件方法和软件方法。
硬件方法一般是使用并口设备(软件狗)或是不标准的软盘(加密盘)。但我还是喜欢软件的方法!

当然,有很多方法提供注册保护,例如购买第三方保护软件,但是我想尝试开发自己的方法,因为我想弄清楚这个问题。

在讨论之前,我略微提一下我以前使用过的方法。

最稳妥和最不安全的办法是提供两种版本:试用版和完整版。当用户注册了你的软件之后,他们就得到一个URL去下载完整版本。完整版
是没有任何限制的,所以软件是否被非法使用就完全依赖于用户的诚实,唯一的约束就是只用注册用户才能得到技术支持。我不使用这
种方法,因为周围有太多的不诚实的用户,会造成注册量太少。

下一个方法是提供用户一个由用户名生成的注册码(公司名可选)。现在软件可以为注册用户使用了。用户可以把软件给其他人使用,
但用户名和公司名是无法修改的。

最后是上一个方法的改良。注册码还是基于版本号,用户可以继续使用老的注册码来进行小的升级,但版本的大改动就需要用户重新注册
了。当然你可以不要用户为版本的升级付费,但这是一个可以选择的方案。

我的办法是在报表上打印和在屏幕上显示最后的用户名和公司名,在证券公司,发票上有程序所打印的公司名,这样即使非法用户有我的
程序,他也无法使用。

现在,问题变成:生成一个基于字符串的唯一值,只要串发生改变,就会引起代码运算出一个不同的值。

解决的办法是使用程序名、用户名、公司名以及版本号作为运算字符串。如果没有输入公司名,就用缺省值代替,这样做的问题是会引起
程序含混。

我是一个电子工程师,在通讯行业里需要一种方法来确定传输的数据是无误的,一般的方法就是CRC。CRC已经使用了20年,我不知道CRC
出现的确切时间,但我知道它一直工作的很好。如果你想知道更多的CRC知识,请参考A PAINLESS GUIDE TO CRC ERROR DETECTION
ALGORITHMS,作者:Ross N. Williams,下载地址:http://www.ross.net。

因此我使用32位的CRC算法得出8位的注册码,有个问题:如果用于运算的字符串没有进行任何的加密就太简单了。所以我使用Delphi的加
密过程加密一下字符串,然后用于运算的字符串就足够复杂了。

我没有做完全的测试,只做了局部的测试,但我保证代码是有效的,特别要提醒的是:CRC结构是基于polynomial modulo算法的,不要修
改它。

我可能很苯,但我不傻:)。下面的代码不是我所使用的,但这些代码很好的演示了我的注册方法是如何工作的。

现在,让我们看看代码。

请注意:我使用了前缀(CamelCase(sic)),以下是定义:

c : 字符型
n : 数字
d : 数据
t : 日期/时间
y : 流通
l : 逻辑型

参数范围:
p : 参数
g : 全局变量

其它的都符合以上规则。

所有的函数和过程都以SSL为前缀,以避免与其他函数和过程重名。这个前缀已在Delphi Prefix Register注册。

unit Registration;

{------------------------------------------------------------------------------}
interface

uses
  SysUtils;

function Mod95(pnVal : Integer): Integer; forward;

function SSLEncode(pcName: String; pcCompany: String; pcAppTitle: String; pcMajor: String): String; forward;

function SSLGenerateKey(pcName, pcCompany, pcApplication, pcMajor : string) : String; forward;

function SSLCrypt(pcString : PChar; pnSeed : Integer = 0) : String ; forward

function CRCExecute(pcString : String) : String ; forward;

var
  gnKey  : Integer;
  gnSalt : Integer;

{------------------------------------------------------------------------------}
implementation

const
  NULL_STRING  = ;

const CRCTable : array [0..255] of LongWord =(
    $00000000, $77073096, $ee0e612c, $990951ba,
    $076dc419, $706af48f, $e963a535, $9e6495a3,
    $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988,
    $09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91,

    $1db71064, $6ab020f2, $f3b97148, $84be41de,
    $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7,
    $136c9856, $646ba8c0, $fd62f97a, $8a65c9ec,
    $14015c4f, $63066cd9, $fa0f3d63, $8d080df5,

    $3b6e20c8, $4c69105e, $d56041e4, $a2677172,
    $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b,
    $35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940,
    $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59,

    $26d930ac, $51de003a, $c8d75180, $bfd06116,
    $21b4f4b5, $56b3c423, $cfba9599, $b8bda50f,
    $2802b89e, $5f058808, $c60cd9b2, $b10be924,
    $2f6f7c87, $58684c11, $c1611dab, $b6662d3d,

    $76dc4190, $01db7106, $98d220bc, $efd5102a,
    $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433,
    $7807c9a2, $0f00f934, $9609a88e, $e10e9818,
    $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01,

    $6b6b51f4, $1c6c6162, $856530d8, $f262004e,
    $6c0695ed, $1b01a57b, $8208f4c1, $f50fc457,
    $65b0d9c6, $12b7e950, $8bbeb8ea, $fcb9887c,
    $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65,

    $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2,
    $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb,
    $4369e96a, $346ed9fc, $ad678846, $da60b8d0,
    $44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9,

    $5005713c, $270241aa, $be0b1010, $c90c2086,
    $5768b525, $206f85b3, $b966d409, $ce61e49f,
    $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4,
    $59b33d17, $2eb40d81, $b7bd5c3b, $c0ba6cad,

    $edb88320, $9abfb3b6, $03b6e20c, $74b1d29a,
    $ead54739, $9dd277af, $04db2615, $73dc1683,
    $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8,
    $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1,

    $f00f9344, $8708a3d2, $1e01f268, $6906c2fe,
    $f762575d, $806567cb, $196c3671, $6e6b06e7,
    $fed41b76, $89d32be0, $10da7a5a, $67dd4acc,
    $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5,

    $d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252,
    $d1bb67f1, $a6bc5767, $3fb506dd, $48b2364b,
    $d80d2bda, $af0a1b4c, $36034af6, $41047a60,
    $df60efc3, $a867df55, $316e8eef, $4669be79,

    $cb61b38c, $bc66831a, $256fd2a0, $5268e236,
    $cc0c7795, $bb0b4703, $220216b9, $5505262f,
    $c5ba3bbe, $b2bd0b28, $2bb45a92, $5cb36a04,
    $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d,

    $9b64c2b0, $ec63f226, $756aa39c, $026d930a,
    $9c0906a9, $eb0e363f, $72076785, $05005713,
    $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38,
    $92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21,

    $86d3d2d4, $f1d4e242, $68ddb3f8, $1fda836e,
    $81be16cd, $f6b9265b, $6fb077e1, $18b74777,
    $88085ae6, $ff0f6a70, $66063bca, $11010b5c,
    $8f659eff, $f862ae69, $616bffd3, $166ccf45,

    $a00ae278, $d70dd2ee, $4e048354, $3903b3c2,
    $a7672661, $d06016f7, $4969474d, $3e6e77db,
    $aed16a4a, $d9d65adc, $40df0b66, $37d83bf0,
    $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9,

    $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6,
    $bad03605, $cdd70693, $54de5729, $23d967bf,
    $b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94,
    $b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d
  );

{------------------------------------------------------------------------------}
function SSLEncode(pcName, pcCompany, pcAppTitle, pcMajor: String): String;
begin
  { Encrypt the data using the major version number to seed the encryption routine }
  SSLCrypt(NULL_STRING, StrToIntDef( pcMajor, 0 ));
  SSLCrypt(PChar( pcAppTitle ));
  SSLCrypt(PChar( pcName ));
  Result := SSLCrypt( PChar( pcCompany ));
end;

{------------------------------------------------------------------------------}
function SSLCrypt(pcString : PChar; pnSeed : Integer = 0) : String ;
var
  nStringLen, nCharCount : Integer;
  nInterim, nChar        : Byte;
  cChar                  : Char;
begin
  nStringLen := length( pcString );
  if nStringLen = 0 then
  begin
    gnKey   := pnSeed;
    gnSalt  := pnSeed * 100;
  end
  else
  begin
    Result := ;
    for nCharCount := 0 to nStringLen - 1 do
    begin
      cChar := pcString[ nCharCount ];
      { only encipher printable characters }
      if (( cChar >= ) and ( cChar <= ~ )) then
      begin
        gnkey    := ( gnkey and $1FFFFFFF ) xor (( gnkey shr 29 ) and $31 );
        nChar    := Byte( cChar );
        nInterim := Mod95(( gnKey div 95 ) - ( nChar - 32 )) + 32;
        Inc( gnSalt );
        if ( gnSalt >= 20857 ) then
          gnSalt := 0;
        gnKey  := gnKey + gnKey + ( nInterim xor nChar ) + gnSalt;
        Result := Result + Char(nInterim);
      end;
    end;
  end;
end;

{------------------------------------------------------------------------------}
function Mod95(pnVal : Integer): Integer;
begin
  Result := pnVal;
  while ( Result >= 9500 ) do
    Result := Result - 9500;

  while ( Result >= 950 ) do
    Result := Result - 950;

  while ( Result >= 95 ) do
    Result := Result - 95;

  while ( Result < 0 ) do
    Result := Result + 95;
end;

{------------------------------------------------------------------------------}
function SSLGenerateKey(pcName, pcCompany, pcApplication, pcMajor : string) : String;
var
  cKey : String;
begin
  cKey := pcName + pcCompany + pcApplication + pcMajor + SSLEncode(pcName, pcCompany, pcApplication, pcMajor);
  Result := CRCExecute( cKey );
end;

{------------------------------------------------------------------------------}
function CRCExecute(pcString : String) : String ;
var
  nX      : Integer;
  nCRCVal : LongWord;
begin
  nCRCVal := 0;
  for nX := 1 to length( pcString ) do
    nCRCVal := CRCTable[Byte(nCRCVal xor Byte(pcString[nX]))] xor (( nCRCVal shr 8 ) and $00FFFFFF );
  Result := LowerCase( IntToHex( nCRCVal, 8 ));
end;

{------------------------------------------------------------------------------}
end.

我写了一个注册机以演示如何工作,当然,你应当修改它以适合自己的需要。

要在你的软件里使用我的注册机制,你需要在工程里包括Registration.pas unit和所有需要的历程。我的检查方法是从一个INI文件里
读入用户名、公司名以及注册码。如果是空的,软件提示一个对话框以提示用户注册,然后计算出注册码并和用户输入的注册码进行比
较,如果用户确认,将信息保存进INI文件并继续执行。此后,所有涉及用户名和公司名的地方重新得到。如果INI文件里不是空的,我
将计算之以确认是否正确。


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·Eclipse + Lomboz + Tomcat JSP 开发配置-JSP教程,Jsp/Servlet
·利用Java调用可执行命令实例-JSP教程,Java技巧及代码
·彻底搞定JSP在线人数-JSP教程,Jsp/Servlet
·数据库操作类实现(C#,SqlClient)-.NET教程,C#语言
·在C#中实现打印功能(C#中PrintDialog,PrintDocument的使用)-.NET教程,C#语言
·结合PHP使用HTML表单(2)-PHP教程,PHP应用
·Java中利用JMF编写摄像头拍照程序-JSP教程,Java技巧及代码
·解析.Net框架下的XML编程技术-.NET教程,XML应用
·ASP.net Logion用户登陆验证代码-.NET教程,Asp.Net开发
·Java中精确计算的一个类用BigDecimal-JSP教程,Java技巧及代码
最新文章
·超越adsense:另类方法赚取巨额收益_网赚技巧
·google adwords优化技巧_网赚技巧
·自己误点adsense广告不用再通知google了_网赚技巧
·用fireworks滤镜轻松制作可爱gif动画_fireworks教程
·网站赚钱:google关键词广告创建的十二高招_站长心得
·提升网站使用性 打造实用性网站_站长心得
·最快速登录到google的10点主要经验_google推广
·制作主页的四十个技巧1_站长心得
·利用rss和gmail备份你的blog_站长心得
·seo终极方法_seo网站优化
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭