首页 > 解决方案 > .NET to Delphi (string.Substring function)

问题描述

I'm trying port a .NET function to Delphi.

Here is the .NET function:

public static string xorEncrypt(string sA, int32 displace)
{
    displace = Math.Abs((((((displace * 82) + (displace / 3)) + (displace % 322)) - (displace % 17)) - ((displace * 7) % 811)));
    string str1 = System.String.Empty;
    string str2 = RWCustom.Custom.EncryptionString;
    int num1 = 0;
    while (num1 < sA.Length) 
    {
        str1 = str1 + (char)((sA.Chars(num1) ^ str2.Chars(((num1 + displace) % str2.Length))));
        num1 = (num1 + 1);
    }
    return str1;
}

And here is my function:

function xorEncrypt(sA: String; displace: Integer): String;
var
   str1: String;
   str2: String;
   num1: Integer;
begin
   Result := '';
   str1 := '';
   str2 := ''; // ?!?
   num1 := 0;
   displace := Abs((((((displace * 82) + (displace div 3)) + (displace mod 322)) - (displace mod 17)) - ((displace * 7) mod 811)));
   while num1 < sA.Length do
   begin
      str1 := str1 + Char(Ord(sA.Chars[num1]) xor Ord(str2.Chars[((num1 + displace) mod str2.Length)]));
      Inc(num1);
   end;
   Result := str1;
end;

So, I already have two problems:

  1. string str2 = RWCustom.Custom.EncryptionString;

    private string EncryptionString
    {
        get
        {
            return this.encrptString.Substring(54, 1447);
        }
    }
    

    encrptString is a String, but looking on mscorlib, the Substring function:

    public string Substring(int32 startIndex, int32 length)
    {
        return this.InternalSubStringWithChecks(startIndex, length, false);
    }
    

    And InternalSubStringWithChecks function:

    internal string InternalSubStringWithChecks(int32 startIndex, int32 length, bool fAlwaysCopy)
    {
        int nt321 = this.Length;
        if (startIndex < 0) 
        {
            throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
        }
        if (startIndex > nt321) 
        {
            throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
        }
        if (length < 0) 
        {
            throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
        }
        if (startIndex > (nt321 - length)) 
        {
            throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
        }
        if (length! == 0) 
        {
            return this.Empty;
        }
        return this.InternalSubString(startIndex, length, fAlwaysCopy);
    }
    

    I have no idea how should be this in Delphi.

  2. (displace / 3) it's a integer division on .NET? Should I change my code to (displace / 3) and set displace to Variant?

标签: .netdelphi

解决方案


Having noted my reservations about this kind of "encryption", let me actually answer the question.

You have a few different problems to contend with, the first among which is that your string indexes are mostly going to be off by one. Remember that Delphi strings are one-based, whereas C# uses zero-based strings, so you need to make adjustments for that. I made a few, but just check every string index you see.

The first place that's going to affect you is in your EncryptionString function:

property EncryptionString: string read GetEncryptionString;

and

function TMyClassNameHere.GetEncryptionString: string;
begin
  Result := Copy(encrptString, 55, 1447); // Was encrptString.Substring(54, 1447)
end;

So while the length remains the same, your string index shifts up by one.

Then, the main function:

 class function TMyClassNameHere.xorEncrypt(sA: string; displace: Integer): string;
 var
   str1: string;
   str2: string;
   num1: Integer;
begin
  displace := Abs((((((displace * 82) + (displace / 3)) +
         (displace mod 322)) -
         (displace mod 17)) -
         ((displace * 7) mod 811)));
  str1 := System.String.Empty;
  str2 := RWCustom.Custom.EncryptionString;
  num1 := 1; // Was 0
  while (num1 <= sA.Length)     do
  begin
    str1 := str1 + Char[(sA[num1] xor str2[((num1 + displace) mod str2.Length)])];
    num1 := num1 + 1;
  end;
  Result := str1;
end;

I changed to a class function (because the original was static). Also, num1 is initialised to one instead of zero.

I think the rest of the calculation should be fine, but I obviously can't test because I don't know what the input is or how it is supposed to work. But this is the Delphi translation I came up with within those constraints.


推荐阅读