Возможно ли преобразовать эту функцию Delphi в метод C #?и как? - PullRequest
1 голос
/ 02 мая 2019

Я работал над преобразованием из Delphi в C #.Обычно это не то, с чем я имею дело.Итак, я смиренно прихожу сюда, чтобы попросить о помощи.

Вот то, что у меня есть:

Код Delphi:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Console in 'Console.pas';

const
  CKEY1 = 11111;
  CKEY2 = 22222;
function EncryptStr(const s: WideString; Key: word): String;
var
  i: integer;
  RStr: RawByteString;
  RStrB: TBytes Absolute RStr;
begin
  Result := '';
  RStr := UTF8Encode(s);
  for i := 0 to Length(RStr) - 1 do
  begin
    RStrB[i] := RStrB[i] xor (Key shr 8);
    Key := (RStrB[i] + Key) * CKEY1 + CKEY2;
  end;
  for i := 0 to Length(RStr) - 1 do
  begin
    Result := Result + IntToHex(RStrB[i], 2);
  end;
end;

function DecryptStr(const s: String; Key: word): String;
var
  i, tmpKey: integer;
  RStr: RawByteString;
  RStrB: TBytes Absolute RStr;
  tmpStr: string;
begin
  tmpStr := UpperCase(s);
  SetLength(RStr, Length(tmpStr) div 2);
  i := 1;
  try
    while (i < Length(tmpStr)) do
    begin
      RStrB[i div 2] := StrToInt('$' + tmpStr[i] + tmpStr[i + 1]);
      Inc(i, 2);
    end;
  except
    Result := '';
    Exit;
  end;
  for i := 0 to Length(RStr) - 1 do
  begin
    tmpKey := RStrB[i];
    RStrB[i] := RStrB[i] xor (Key shr 8);
    Key := (tmpKey + Key) * CKEY1 + CKEY2;
  end;
  Result := UTF8Decode(RStr);
end;

var myEncrypted: string;
begin
  try
    myEncrypted := EncryptStr('TheTestString', 4444);
    WriteLn('Encrypted: '+myEncrypted);
    ExitCode := 1;
    Console.WaitAnyKeyPressed('Press any key to continue ...');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Часть причины, по которой я нахожусьэто означает, что этот код возник здесь (не мой) delphi-simple-string-encryption .

Вот что я пытался сделать до сих пор:

C #код:

private const int CKEY1 = 11111;
private const int CKEY2 = 22222;
public static string EncryptAString(string s, int Key)
{
    try
    {
        var encryptedValue = string.Empty;
        // Create a UTF-8 encoding.
        UTF8Encoding utf8 = new UTF8Encoding();
        // Encode the string.
        byte[] RStrB = utf8.GetBytes(s);           

        for (var i = 0; i <= RStrB.Length - 1; i++)
        {
            RStrB[i] = Convert.ToByte(RStrB[i] ^ (Key >> 8));
            Key = (RStrB[i] + Key) * CKEY1 + CKEY2;
            //I have a problem right here. See screen shot for values
        }
        for (var i = 0; i <= RStrB.Length - 1; i++)
        {
            encryptedValue = encryptedValue + RStrB[i].ToString("X2");
        }
        return encryptedValue;
    }
    catch (Exception)
    {
        throw;
    }
}

Delphi enter image description here C # enter image description here

Код C # в конечном итоге выдает эту ошибку: Ошибка:

System.OverflowException: значение было слишком большим или слишком маленьким для неподписанного байта.в System.Convert.ToByte (значение Int32) в ChronicleConvertText.Program.EncryptAString (String s, ключ Int32) в C: \ Users \ todd7 \ source \ repos \ ChronicleConvertText \ ChronicleConvertText \ Program.cs: строка 70 в ChronicleConvertTextProgram.Main (String [] args) в C: \ Users \ todd7 \ source \ repos \ ChronicleConvertText \ ChronicleConvertText \ Program.cs: строка 17

В процессе исследования этого несколько вещей оказались в центре внимания.

  • В Delphi у меня есть это предупреждение: [dcc32 Warning] Project1.dpr (58): W1000 Символ 'UTF8Decode' устарел: 'Использовать UTF8ToWideString или UTF8ToString'.Имейте в виду, что используется существующий код.Итак, я не смотрел напрямую на то, что произойдет, если произойдет какое-либо влияние на переключение на «UTF8ToWideString или UTF8ToString».Моя задача заключается в том, чтобы посмотреть, смогу ли я продублировать ее, если это возможно.
  • Другая проблема заключается в следующем: опасности преобразования двоичных данных в строку .

Я подозреваю, что это может быть моим непониманием того, что происходит в «xor» в стихах Delphi «^» в C #.Остается главный вопрос: можно ли это сделать?и как?Спасибо за любую помощь.

Ответы [ 2 ]

2 голосов
/ 02 мая 2019

Ваши константы CKEY1 и CKEY2 и аргумент Key имеют тип int.Таким образом, выражение

Key = (RStrB[i] + Key) * CKEY1 + CKEY2;

вычисляется с использованием 32-битных значений.Например:

(4444 + 84) * 11111 + 22222 = 50 332 830

близко к отображаемому значению, не так ли?

В коде Delphi используются 16-разрядные переменные без знака и соответствующая арифметика, эквивалент C # для Delphi word равенushort

1 голос
/ 02 мая 2019

Вот что у меня получилось:

    private const short CKEY1 = 11111;
    private const short CKEY2 = 22222;
    public static string EncryptAString(string s, ushort Key)
    {
        try
        {
            var encryptedValue = string.Empty;
            // Create a UTF-8 encoding.
            UTF8Encoding utf8 = new UTF8Encoding();
            // Encode the string.
            byte[] RStrB = utf8.GetBytes(s);

            for (var i = 0; i <= RStrB.Length - 1; i++)
            {
                RStrB[i] = Convert.ToByte(RStrB[i] ^ (Key >> 8));
                Key = (ushort)(((RStrB[i] + Key) * CKEY1) + CKEY2);
            }
            for (var i = 0; i <= RStrB.Length - 1; i++)
            {
                encryptedValue = encryptedValue + RStrB[i].ToString("X2");
            }
            return encryptedValue;
        }
        catch (Exception)
        {
            throw;
        }
    }

Протестировано с кодом Delphi, и оно прекрасно работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...