procedure TForm1.btn1Click(Sender: TObject);
var d:string;
    esi,edi,i:Integer;
begin
  d:=Trim(edt1.Text);
  edi:=2005;
  esi:=0;
  for i:= 1 to Length(d) do
    begin
      edi:=edi+ (esi + 1) * ord(d[i]);
      esi:=esi+1;
    end;
    edt1.Text:=IntToStr(edi);
end;如果已知计算结果为:13636;
那么如何把算法逆回去,得知EDT1.TEXT的值。

解决方案 »

  1.   

    k[0] = 2005                  i = 0
    k[1] = K[0] + (1) * a[1]     i = 1
    k[1] = K[1] + (2) * a[2]     i = 2
    ......
    k[i] := k[i - 1] + ((i - 1) + 1) * a[i];(i > 0, 32 <= a[i] <255);
    呵呵,穷举法吧,让计算机去跑先让 i = 1 也就是d是一个字符,从32到254循环一圈,看看结果是否等于13636
    然后在让i = 2 也就是d是两个字符,每个字符都从32到254扫描,看看哪个结果等于 13636
    ......
    呵呵,估计你的计算机德累死
      

  2.   

    这有无究个解,不存在一一对应的可逆性建议你先算出d的长度n(或用最大值和最小值,估算出n)先定下ord的范围.这样得出的结果就会是有很个的了13636=2005+∑i*ord(d[i])  i=1..n
      

  3.   

    这个hash算法也太破了吧,就这个13636就别想穷举了,就算把每个字符约束在64种可能以内,满足条件的字符串的数量级也至少在 2^78 (78=6*13) 以上,而且这个数量级本身的数量级很可能也被低估了uses Generics.Collections; { >= D2009 }const
      IPwdMaxSize = 32;
      IMinPwdChar = Ord('0');
      IMaxPwdChar = Ord('z');
      IDefMaxGet  = 256;type
      //TPwdList = TStringList;  { < D2009 }
      TPwdList  = TList<AnsiString>; { >= D2009 }  TPwdFinder  = class
      private
        FHashValue, FMinIndex, FMaxIndex  : Integer;
        procedure SetHashValue(Value: Integer);
      public
        class function Hash(const S: AnsiString): Integer;
        constructor Create(Hash: Integer);    function GetAllPwds(List: TPwdList; MaxCount: Integer = IDefMaxGet): Integer;
        function GetPasswords(List: TPwdList; Len: Integer = 0;
          MaxCount: Integer = IDefMaxGet): Integer;    property HashValue: Integer read FHashValue write SetHashValue;
        property MinIndex: Integer read FMinIndex;
        property MaxIndex: Integer read FMaxIndex;
      end;var
      nRanges : array[1..IPwdMaxSize]of record
          iRangeMin, iRangeMax: Integer;
        end;
      bolRangeInited: Boolean;{ TPwdFinder }constructor TPwdFinder.Create(Hash: Integer);
      procedure InitRanges;
      var
        i, nSum : Integer;
      begin
        nSum  := 0;
        for i:=1 to IPwdMaxSize do
        begin
          Inc(nSum, i);
          with nRanges[i] do
          begin
            iRangeMin := nSum * IMinPwdChar;
            iRangeMax := nSum * IMaxPwdChar;
          end;
        end;
        bolRangeInited  := True;
      end;
    begin
      if(not bolRangeInited)then InitRanges;
      HashValue := Hash;
    end;function TPwdFinder.GetAllPwds(List: TPwdList; MaxCount: Integer): Integer;
    var i: Integer;
    begin
      Result  := 0;
      if((HashValue=0)or(MaxCount<=0))then Exit;
      for i:=MinIndex to MaxIndex do
      begin
        Inc(Result, GetPasswords(List, i, MaxCount - Result));
        if(Result>=MaxCount)then Exit;
      end;
    end;function TPwdFinder.GetPasswords(List: TPwdList; Len, MaxCount: Integer): Integer;
    var
      str: AnsiString;
      procedure GetCharAtIndex(Hash, Index: Integer);
      var
        b, i  : Byte;
        nHash : Integer;
      begin
        if(Index=1)then
        begin
          str[1]  := AnsiChar(Hash);
          Inc(Result);
          List.Add(str);
          Exit;
        end;    i := IMaxPwdChar+1;
        for b:=IMinPwdChar to IMaxPwdChar do
        begin
          nHash := Hash - b * Index;
          if(nHash>nRanges[Index-1].iRangeMax)then
            Continue;
          i := b;
          Break;
        end;    for b:=i to IMaxPwdChar do
        begin
          nHash := Hash - b * Index;
          if(nHash<nRanges[Index-1].iRangeMin)then
            Break;
          str[Index]  := AnsiChar(b);
          GetCharAtIndex(nHash, Index-1);
          if(Result>=MaxCount)then Break;
        end;
      end;
    begin
      Result  := 0;
      if((HashValue=0)or(MaxCount<=0))then Exit;
      if(Len<MinIndex)then Len := MinIndex;
      if(Len>MaxIndex)then Len := MaxIndex;
      SetLength(str, Len);
      GetCharAtIndex(HashValue - 2005, Len);
    end;class function TPwdFinder.Hash(const S: AnsiString): Integer;
    var i: Integer;
    begin
      Result  := 2005;
      for i := 1 to Length(S) do
        Inc(Result, i * Byte(S[i]));
    end;procedure TPwdFinder.SetHashValue(Value: Integer);
    var i: Integer;
    begin
      Dec(Value, 2005);
      FHashValue  := 0;
      FMinIndex   := 0;
      FMaxIndex   := 0;  for i:=1 to IPwdMaxSize do
      begin
        if(Value>nRanges[i].iRangeMax)then
          Continue;
        FMinIndex := i;
        Break;
      end;
      if(FMinIndex=0)then Exit;  for i:=FMinIndex+1 to IPwdMaxSize do
      begin
        if(Value>=nRanges[i].iRangeMin)then
          Continue;
        FMaxIndex := i - 1;
        Break;
      end;
      if(FMaxIndex=0)then
        FMaxIndex := IPwdMaxSize;
      FHashValue  := Value + 2005;
    end;
    测试代码:procedure TForm2.Button1Click(Sender: TObject);
    var
      pwd : TPwdFinder;
      lst : TPwdList;
      s   : AnsiString;
    begin
      s := AnsiString(Edit1.Text);
      pwd := TPwdFinder.Create(TPwdFinder.Hash(s));
      lst := TPwdList.Create;
      with pwd do
      Memo1.Text  := Format('"%s"(%d): [%d..%d]', [s, HashValue, MinIndex, MaxIndex]);
      Memo1.Lines.BeginUpdate;
      try
        Memo1.Lines.Add(Format('%d found:', [pwd.GetAllPwds(lst)]));
        for s in lst do
          Memo1.Lines.Add(string(s));
      finally
        Memo1.Lines.EndUpdate;
        lst.Free;
        pwd.Free;
      end;
    end;procedure TForm2.Button2Click(Sender: TObject);
    var
      pwd : TPwdFinder;
      lst : TPwdList;
      s   : AnsiString;
    begin
      pwd := TPwdFinder.Create(13636);
      lst := TPwdList.Create;
      with pwd do
      Memo1.Text  := Format('%d: [%d..%d]', [HashValue, MinIndex, MaxIndex]);
      Memo1.Lines.BeginUpdate;
      try
        Memo1.Lines.Add(Format('Found: %d', [pwd.GetPasswords(lst)]));
        for s in lst do
          Memo1.Lines.Add(Format('%d'#9'"%s"', [TPwdFinder.Hash(s), s]));
      finally
        Memo1.Lines.EndUpdate;
        lst.Free;
        pwd.Free;
      end;
    end;顺便说下,不要把 MaxCount 传的太大,而且 edit1 里的字符串长度最好不要超过3个,不然 windows 自带的 memo 控件更新不过来。这个 13636 的话,算到你死也穷举不完的