⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mybpstring.pas

📁 说明:支持标准MD5、SHA1、Inno密码、QQ密码、Serv-U密码。 支持多线程。 支持进度保存、读取。
💻 PAS
字号:
Unit MyBPString;

Interface

Uses SyncObjs;

(**********************************************************************
  用例:
      procedure TForm1.Button1Click(Sender: TObject);
      var
        e :TMyEnumStrAny;
      begin
        e.s     := Edit1.Text;                        {字符元素串}
        e.si    := 1;                                 {起始字符元素位置}
        e.sLen  := ord(e.s[0]);                       {字符元素总数}
        e.pi    := 1;                                 {起始档位置}
        e.pMax  := StrToIntDef(Edit2.Text, 1);
        if (e.pMax > SizeOf(e.p)) then exit;
        ListBox1.Clear;
        while MyEnumStrAny(e) do ListBox1.Items.Add(MyGetEnumStr(e));
      end;
**********************************************************************)

//  列举字符串中任意字符的任意组合 ( 穷举 )
Type
  TMyEnumStrAny = Packed Record         {列举字符串中任意字符的任意组合的数据结构}
    S: String[255];                     {被列举的字符串}
    sI: integer;                        {指向 s 中的位置}
    sLen: Byte;                         {被列举的字符串长}
    P: Array[1..32] Of Byte;            {已经列举的字符在 s 中的位置}
    Pi: Byte;                           {指向 s 中的位置}
    pMax: Byte;                         {要列举出的字符串最大的字符个数}
  End;
  {  返回:  按 pMax 的长, 未列举完时返回 true, 否则返回 false, 每次调用列举出一个新的组合
           各位字符在 TMyEnumStrAny.s 中的位置存放在 TMyEnumStrAny.p 中, 按 s[p[i]]取出
           各位字符.

    备注:  此函数采用算盘加法原理(满档进一)来处理的.
  }

Function MyEnumStrAny(Var e: TMyEnumStrAny): Boolean;
Function MyGetEnumStr(Var e: TMyEnumStrAny): String;

Implementation

Var
  mCS: TCriticalSection;                {设置临界处理对象, 防止共享数据时的冲突}


Function MyEnumStrAny(Var e: TMyEnumStrAny): Boolean;
Var
  I, P: Byte;
Begin
  mCS.Enter;
  Result := true;                       {注释用算盘加法原理来描述}
  If (e.sI <= e.sLen) Then
  Begin                                 {如果未满档时}
    e.P[e.Pi] := e.sI;                  {原档位上一珠}
    inc(e.sI);                          {下一粒珠的位置}
    mCS.Leave;
    Exit;                               {返回}
  End;                                  {如果是满档叶}
  e.sI := 1;                            {第一粒珠位置}
  For I := 1 To e.Pi Do
  Begin
    P := e.P[I];
    If (P < e.sLen) Then
      Break;                            {查已使用了的档是否有未满档的}
  End;
  If (I > e.Pi) And (e.Pi = e.pMax) Then
  Begin                                 {如果已使用了的档是全满档时}
    Result := false;                    {并且档数已经达到要求时, 说明所有列举已经完成}
    mCS.Leave;
    Exit;
  End;
  For I := e.Pi Downto 2 Do
  Begin                                 {满档进一处理}
    P := e.P[I];
    If (P < e.sLen) Then
      Break;                            {如果要处理的当前档未满档时不处理}
    P := e.P[I - 1];
    If (P = e.sLen) Then
      Break;                            {如果要处理的当前档的前一档已满档时不处理}
    e.P[I] := 1;                        {否则当前档为第一粒珠}
    e.P[I - 1] := e.P[I - 1] + 1;       {前一档加多一粒珠}
  End;
  For I := 1 To e.Pi Do
  Begin
    P := e.P[I];
    If (P < e.sLen) Then
      Break;                            {档数未达到要求时 查已使用了的档是否有未满档的}
  End;
  If (I > e.Pi) Then
  Begin                                 {如果已使用了的档是全满档时}
    inc(e.Pi);                          {增加一新档位, 已使用了的档全满档进位处理}
    For I := 1 To e.Pi Do
      {if e.Pi-1=i then }
      e.P[I] := 1;                      {都上第一粒珠}
  End;
  inc(e.sI);                            {下一粒珠的位置}
  mCS.Leave;
End;

(**********************************************************************
  取调用 MyEnumStrAny 后列举出的字符串
**********************************************************************)
Function MyGetEnumStr(Var e: TMyEnumStrAny): String;
Var
  I: Byte;
Begin
  mCS.Enter;
  Result := '';
  For I := 1 To e.Pi Do
    Result := Result + e.S[e.P[I]];
  mCS.Leave;
End;

{装入时初始化}
Initialization
  mCS := TCriticalSection.Create;
  {关闭时}
Finalization
  mCS.Free;

End.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -