我现在的程序,想通过验证CDKEY来确定系统的用户数目和过期日期。想请教一下具体实现的思路和方法,谢谢。

解决方案 »

  1.   

    //呵呵,以下是我自己创造的一对函数,希望可以帮的上楼主!  ^_^
    //给定用户ID和客户序号产生28为CDKEY
    //Length(UserLen)<=10
    function GetEasyCDKEY(UserID:String;UserIndex:Integer):String;
    var
      DATAStr:String;
      TS:Comp;
      i,j,CheckSum:Integer;
    begin
      TS:=TimeStampToMSecs(DateTimeToTimeStamp(Now));
      DATAStr:=IntToHex(PInt64(@TS)^,12)+IntToHex(UserIndex XOR $77777777,8);
      CheckSum:=1;
      j:=1;
      for i:=1 to Length(UserID) do
      begin
        Inc(CheckSum,Ord(UserID[i])+Ord(DATAStr[j])-64);
        Inc(j);
        if j>20 then j:=1;
      end;
      Result:=DATAStr+IntToHex(CheckSum XOR $77777777,8);
    end;
    //检测用户和CDKEY有效性,如果检测成功返回True同时返回注册时间和用户序号.
    function CheckEasyCDKEY(UserID,CDKEY:String;var regDateTime:TDateTime;var UserIndex:Integer):Boolean;
    var
      DATAStr:String;
      TS:Comp;
      i,j,CheckSum:Integer;
    begin
      Result:=False;
      if Length(CDKEY)<>28 then Exit;
      DATAStr:=Copy(CDKEY,1,20);
      CheckSum:=1;
      j:=1;
      for i:=1 to Length(UserID) do
      begin
        Inc(CheckSum,Ord(UserID[i])+Ord(DATAStr[j])-64);
        Inc(j);
        if j>20 then j:=1;
      end;
      try
        if CheckSum<>(StrToInt('$'+Copy(CDKEY,21,8)) XOR $77777777) then Exit;
        PInt64(@TS)^:=StrToInt64('$'+Copy(DATAStr,1,12));
        regDateTime:=TimeStampToDateTime(MSecsToTimeStamp(TS));
        UserIndex:=StrToInt('$'+Copy(DATAStr,13,8)) XOR $77777777;
      except
        on E:Exception do Exit;
      end;
      Result:=True;
    end;
    //测试
    procedure TForm1.Button1Click(Sender: TObject);
    var
      R:String;
      regdt:TDateTime;
      UserIndex:Integer;
    begin
      R:=GetEasyCDKEY('quanqi',100);
      if CheckEasyCDKEY('quanqi',R,regdt,UserIndex) then
      ShowMessage(R+#13
                  +DateTimeToStr(regdt)+#13
                  +IntToStr(UserIndex));
    end;