Перевод кода Delphi в C# (Blowfish)

Я не разработчик 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;

Почему существует предопределенный размер формата? Есть ли другая трансформация с помощью blowfish (DECUtil)?

и режим:

Mode := TCipherMode(0);

в Delphi источник шифра

(http://www.koders.com/delphi/fidE1F5EC890EF9FD7D5FFEB524898B00BC8403B799.aspx) параметр 'mode' имеет следующий порядок: cmCTS, cmCBC, cmCFB, cmOFB, cmECB, cmCTSMAC, cmCBCMAC, cmCBMAC, cmC

Итак, я полагаю, что в Delphi режим 0 это cmCTS ... но на самом деле я не знаю.

пример результата: пользователь: ADMIN pass: ADMIN ---> pass: fAtP3sk=

5 ответов

Решение

Значение FStringFormat переменная (4196) равна использовать fmtMIME64 const определен в блоке DECUtil, который определен так

 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;

Глядя на источник для Delphi Object TCipher_Blowfish, есть несколько констант, объявленных для формата String.

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;
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 имеет числовое значение 0, cmCBC 1 и т. Д.

Код должен быть правильно написан

FMode := cmCTS;

который не только меньше символов для ввода, но гораздо понятнее для тех, кто читает его в будущем (как вы).:-)

FStringFormat:=4196;

Это просто присваивание значения переменной, FStringFormat является целочисленным значением, которое было объявлено, и теперь вы задаете ему значение.

Во первых спасибо за все ответы!!

Я не знаю, могу ли я выложить решение здесь, но если возможно, я могу помочь кому-нибудь...

наконец я преобразовал код 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.

и использовать эту DLL в C# следующим образом:

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);
        }

это не супер чистый, но делать работу...

Другие вопросы по тегам