将Delphi代码翻译成C#(Blowfish)

时间:2012-09-05 16:33:29

标签: c# delphi encryption blowfish encryption-symmetric

我不是Delphi的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);

在delphi的Cipher源代码中

  

(http://www.koders.com/delphi/fidE1F5EC890EF9FD7D5FFEB524898B00BC8403B799.aspx)   参数'mode'具有以下顺序:   cmCTS,cmCBC,cmCFB,cmOFB,cmECB,cmCTSMAC,cmCBCMAC,cmCFBMAC

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

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

5 个答案:

答案 0 :(得分:2)

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

 fmtMIME64      = $1064;     // MIME Base 64

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

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

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

现在关于这一行

模式:= TCipherMode(0);

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

 TCipherMode = (cmCTS, cmCBC, cmCFB, cmOFB, cmECB, cmCTSMAC, cmCBCMAC, cmCFBMAC);
在这种情况下,

相当于写。

Mode := cmCTS;

答案 1 :(得分:2)

查看Delphi对象TCipher_Blowfish的源代码,有一些为String Format声明的常量。

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;

答案 2 :(得分: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的数值为0cmCBC 1,等等。

代码应该已正确编写

FMode := cmCTS;

不仅可以输入更少的字符,而且对于将来阅读它的人来说更加清晰(像你一样)。 : - )

答案 3 :(得分:0)

FStringFormat:=4196;

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

答案 4 :(得分: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);
        }

它不是超级干净但是做这个工作......