Перевод кода 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);
}
это не супер чистый, но делать работу...