unit DbHaspPwd;

interface

uses
  Windows, SysUtils;

function GetHaspPass1: LongInt;

function GetHaspPass2: LongInt;

type
  PAuthorizeFile = ^TAuthorizeFile;
  TAuthorizeFile = packed record
    Head: string[20];
    Version: Word;
    Edition: Byte;
    Hours: Integer;
    Times: Word;
    Key1: array [0..11] of Byte;
    Key2: array [0..11] of Byte;
  end;

const
  // 未加密长度
  Length_AuthorizeData = 54;
  // 加密后长度
  Length_AuthorizeFile = 60;

const
  ScEncryptKey: array [0..16] of Byte =
    ($00, $00, $00, $0D, $CF, $CB, $CD, $CF,
     $8C, $8B, $BC, $90, $8D, $8B, $92, $9E,
     $AC);
  ScAuthorizeKey: array [0..16] of Byte =
    ($00, $00, $00, $0D, $8C, $8B, $BC, $90,
     $8D, $8B, $92, $9E, $8F, $AC, $9E, $8C,
     $B7);

  HASP_MemorySizeInByte = 48;

  HASP_AuthorizeFileHead = 'SmartCost Auth.';
  
implementation

const
  // Demo
  //Ps1: array [0..8] of Byte = ($00, $00, $00, $05, $CE, $C8, $CA, $CB, $CE);
  //Ps2: array [0..7] of Byte = ($00, $00, $00, $04, $CC, $CD, $C6, $C9);

  Ps1: array [0..8] of Byte = ($00, $00, $00, $05, $CD, $C6, $CB, $CA, $CD);
  Ps2: array [0..8] of Byte = ($00, $00, $00, $05, $CF, $CA, $CE, $C8, $CE);
// HASP密码  
function ExtractPwd(AArray: array of Byte; ALength: Integer): LongInt;
var
  OrgLength, I, iTemp: Integer;
  TestBuf: array [0..1023] of Char;
  TargetBuf: array [0..1027] of Char;
  strHexLength: string[8];
  strTemp: string;
begin
  ZeroMemory(@TestBuf, 1024);
  ZeroMemory(@TargetBuf, 1028);
  CopyMemory(@TargetBuf, @AArray, ALength*SizeOf(Char));
  strHexLength := '';
  for I := 0 to 3 do
  begin
    strHexLength := strHexLength + IntToHex(Byte(TargetBuf[I]), 2);
  end;
  OrgLength := StrToInt('$' + strHexLength);
  for I := 0 to OrgLength - 1 do
  begin
    if not Odd(I) then
    begin
      if (I + 1 < OrgLength) then
        TestBuf[I] := TargetBuf[I + 1 + 4]
      else
        TestBuf[I] := TargetBuf[I + 4];
    end
    else
      TestBuf[I] := TargetBuf[I - 1 + 4];
  end;
  for I := 0 to OrgLength - 1 do
  begin
    TargetBuf[I] := Char($FF - Byte(TestBuf[I]));
  end;
  for I := 0 to OrgLength - 1 do
  begin
    TestBuf[I] := TargetBuf[OrgLength - I - 1];
  end;
  SetString(strTemp, PChar(@TestBuf[0]), ALength);
  Result := StrToInt(strTemp);
end;

function GetHaspPass1: LongInt;
begin
  Result := ExtractPwd(Ps1, Length(Ps1));
end;

function GetHaspPass2: LongInt;
begin
  Result := ExtractPwd(Ps2, Length(Ps2));
end;

end.
