1

我不是 Delphi 开发者,但我必须将此 delphi 代码转换为 C#:

Function EncodeClave(Clave:String):String;
 var
   R: String;
   FStringFormat:Integer;
 begin
   FStringFormat:=4196;
 with TCipher_Blowfish.Create('CLAVE', nil) do
  try
    Mode := TCipherMode(0);
    R := CodeString(Clave, paEncode, FStringFormat);
    Result := R;
  finally
    Free;
  end;
 end;

我在研究中发现了以下网站:

http://www.bouncycastle.org/csharp/

http://www.schneier.com/code/blowfish.cs

我不明白这条线:

FStringFormat:=4196;

为什么有预定义的格式大小?河豚(DECUtil)是否有另一种转变?

和模式:

Mode := TCipherMode(0);

在Cipher的delphi源码中

(http://www.koders.com/delphi/fidE1F5EC890EF9FD7D5FFEB524898B00BC8403B799.aspx)参数“模式”具有以下顺序:cmCTS、cmCBC、cmCFB、cmOFB、cmECB、cmCTSMAC、cmCBCMAC、cmCFBMAC

所以我想在delphi中模式0是cmCTS ...但实际上我不知道。

结果示例: user : ADMIN pass : ADMIN ---> pass : fAtP3sk=

4

5 回答 5

2

变量 (4196)的值FStringFormat等于使用DECUtil单元中定义的fmtMIME64const,其定义如下

 fmtMIME64      = $1064;     // MIME Base 64

此值用于格式化传递给 CodeString 方法的字符串。在这种情况下,这条线

 R := CodeString(Clave, paEncode, FStringFormat);

Clave以 MIME Base 64 格式返回变量的值。

现在关于这条线

模式 := TCipherMode(0);

您正在将 Mode 属性设置为枚举的第一个值。

 TCipherMode = (cmCTS, cmCBC, cmCFB, cmOFB, cmECB, cmCTSMAC, cmCBCMAC, cmCFBMAC);

在这种情况下相当于写。

Mode := cmCTS;
于 2012-09-05T17:20:23.887 回答
2

查看 Delphi 对象TCipher_Blowfish的源代码,有一些为字符串格式声明的常量。

fmtMIME64      = $1064;     // MIME Base 64

“$”在 delphi 中定义了一个十六进制数,因此在您的示例代码中使用了 $1064 = 4196。

TCipherMode(0);

TCipherMode 是对以下枚举类型的引用:

TCipherMode = (cmCTS, cmCBC, cmCFB, cmOFB, cmECB, cmCTSMAC, cmCBCMAC, cmCFBMAC);

所以 TCipherMode(0) = cmCTS

如果您进行这些替换,代码会更容易理解:

Function EncodeClave(InputString:String):String;
 var
   BlowfishObj: TCipher_Blowfish;
 begin

  BlowfishObj := TCipher_Blowfish.Create('CLAVE', nil);
  try

    BlowfishObj.Mode := cmCTS;  // (Cipher Text Stealing)
    Result := BlowfishObj.CodeString(InputString, paEncode, fmtMIME64);

  finally
    BlowfishObj.Free;
  end;
 end;
于 2012-09-05T17:22:02.640 回答
1
var 
  FStringFormat: Integer; 
begin 
  FStringFormat := 4196; 

是相同的

Int32 FStringFormat; 
FStringFormat = 4196; 

在 C# 中。

FMode := TCipherMode(0);' 是整数到枚举值的类型。Delphi 枚举与 C# 中的枚举几乎相同;默认情况下,它们从 开始0,因此枚举

type
  TCipherMode = ( cmCTS, cmCBC, cmCFB, cmOFB, cmECB, cmCTSMAC, cmCBCMAC, cmCFBMAC);

表示它cmCTS的数值为0cmCBC1 等。

代码应该已经正确编写

FMode := cmCTS;

这不仅减少了要输入的字符,而且对于将来阅读它的人(比如你)来说更清晰。:-)

于 2012-09-05T17:14:45.027 回答
0
FStringFormat:=4196;

这纯粹只是给变量赋值,FStringFormat是一个声明的整数值,现在你给它一个值。

于 2012-09-05T16:41:31.033 回答
0

首先感谢所有答案!

我不知道我是否可以在这里发布解决方案,但如果我可以帮助任何人......

最后,我已经将 delphi 代码转换为 DLL,如下所示:

library crypto;

   uses
  Cipher in '\Source\Cipher.pas',
  DECUtil in '\Source\DECUtil.pas',
  Hash in '\Source\Hash.pas',
  SysUtils;

{$R *.res}

Function EncodeClave(Clave:String):String;
var
  R: String;
  FStringFormat:Integer;
begin
  FStringFormat:=4196;
  with TCipher_Blowfish.Create('CLAVE', nil) do
  try
    Mode := TCipherMode(0);
    R := CodeString(Clave, paEncode, FStringFormat);
    Result := R;
  finally
    Free;
  end;
end;

function MsgEncode(pIn: PWideChar; out pOut: PWideChar): LongBool; stdcall;
var
  sOut: string;
  BuffSize: Integer;
begin
  sOut := EncodeClave(pIn);
  BuffSize := SizeOf(Char)*(Length(sOut)+1);
  GetMem(pOut, BuffSize);
  FillChar(pOut^, BuffSize, 0);
  Result := Length(sOut)>0;
  if Result then
    Move(PChar(sOut)^, pOut^, BuffSize);
end;

procedure BlockFree(p: Pointer); stdcall;
begin
  FreeMem(p);
end;

exports
  MsgEncode,
  BlockFree;

begin
end.

并像这样在 C# 中使用这个 DLL:

class Program
    {
        [DllImport("crypto.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool MsgEncode(string pIn, out IntPtr pOut);

        [DllImport("crypto.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        public static extern void BlockFree(IntPtr p);

        static void Main(string[] args)
        {
            IntPtr pOut;

            string encode = "admin";
            string encoded = "";


            if (MsgEncode(encode, out pOut))
                encoded = Marshal.PtrToStringAnsi(pOut);
            BlockFree(pOut);

            Console.WriteLine("String Encoded '" + encode + "' : " + encoded);
        }

它不是超级干净,但做的工作......

于 2012-09-07T01:38:41.637 回答