How can I convert this XOR encryption function from Delphi to C #?

The following Delphi routine comes from a long-standing publication of CompuServe and is used to encrypt various information in our database. Below are both Delphi 2007 and (thanks to some SO help with Unicode differences) versions of Delphi XE.

We are trying to convert this to C # and got close-ish, but we missed something. Unfortunately, our Delphi guy (I) does not know C #, and the C # guy is new to Delphi. C # does not (seem) to have the concept of AnsiString, so the solution is likely to include bytes or char arrays?

We will be very grateful for the help in converting this file to C #.

Delphi 2007 Version (ASCII)

function EncodeDecode(Str: string): string; const Hash: string = '^%12hDVjED1~~#29afdmSD`6ZvUY@hbkDBC3fn7Y7euF|R7934093*7a-|- Q`'; var I: Integer; begin for I := 1 to Length (Str) do Str[I] := chr (ord (Str[I]) xor not (ord (Hash[I mod Length (Hash) + 1]))); Result := Str; end; 

Delphi XE Version (Unicode)

 function TfrmMain.EncodeDecode(Str: AnsiString): AnsiString; const Hash: string = '^%12hDVjED1~~#29afdmSD`6ZvUY@hbkDBC3fn7Y7euF|R7934093*7a-|- Q`'; var I: Integer; begin Result := Str; for I := 1 to Length (Result) do Result[I] := AnsiChar (ord (Result[I]) xor not (Ord (Hash[I mod Length (Hash) + 1]))); end; 
+8
c # delphi encryption
source share
2 answers

I don't know C # either, so this is probably seriously non-idiomatic.

 static string EncodeDecode(string str) { byte[] hash = new byte[63] { 94, 37, 49, 50, 104, 68, 86, 106, 69, 68, 49, 126, 126, 35, 50, 57, 97, 102, 100, 109, 83, 68, 96, 54, 90, 118, 85, 89, 64, 104, 98, 107, 68, 66, 67, 51, 102, 110, 55, 89, 55, 101, 117, 70, 124, 82, 55, 57, 51, 52, 48, 57, 51, 42, 55, 97, 45, 124, 45, 32, 32, 81, 96 }; Encoding ANSI = Encoding.GetEncoding(1252); byte[] input = ANSI.GetBytes(str); byte[] output = new byte[input.Length]; for (int i = 0; i < input.Length; i++) output[i] = (byte)(input[i] ^ ~hash[(i + 1) % hash.Length]); return ANSI.GetString(output); } 

I assumed that your ANSI strings were encoded using Windows 1252, but you must have encoded your legacy data using a different code page, it is pretty obvious how to change it.

Since C # does not have the equivalent of 8-bit Delphi string types, it would be very difficult for me personally to use byte[] rather than string .

Done looks like this:

 static byte[] EncodeDecode(byte[] input) { byte[] hash = new byte[63] { 94, 37, 49, 50, 104, 68, 86, 106, 69, 68, 49, 126, 126, 35, 50, 57, 97, 102, 100, 109, 83, 68, 96, 54, 90, 118, 85, 89, 64, 104, 98, 107, 68, 66, 67, 51, 102, 110, 55, 89, 55, 101, 117, 70, 124, 82, 55, 57, 51, 52, 48, 57, 51, 42, 55, 97, 45, 124, 45, 32, 32, 81, 96 }; byte[] output = new byte[input.Length]; for (int i = 0; i < input.Length; i++) output[i] = (byte)(input[i] ^ ~hash[(i + 1) % hash.Length]); return output; } 

@Groo makes an excellent point at which a hash can be initialized with a cleaner listing of this:

 byte[] hash = ANSI.GetBytes(@"^%12hDVjED1~~#29afdmSD`6ZvUY@hbkDBC3fn7Y7euF|R7934093*7a-|- Q`"); 
+11
source share

String in C # is a sequence of characters encoded in UTF-16, as described in this article by John Skeet . This really shouldn't concern you at all until you decide to serialize it to binary (i.e., Convert it to an array of bytes). In this case, there is a class called Encoding in the System.Text namespace that supports String encoding with whatever encoding you want.

An AnsiString in Delphi is basically an ASCII string (no, it's really an ANSI string, as the name says), where each character is guaranteed to have exactly 8 bits. This is a relatively β€œsimple” encoding encoding for work, as it has a fixed size, is widespread and compatible with legacy systems (but does not allow encoding of more than 255 characters).

In other words, both of your versions are of the same encoding type, but the unicode version now explicitly specifies obsolete strings like AnsiString s. This means that the latest version does not actually support Unicode strings, but the type must be changed using the new Delphi version.

What @David did when I wrote this long bullshit is basically what I was going to write, except that I would use Encoding.ASCII instead ( [edit] and fail because ASCII uses only the lower 7 bits to encode characters, as mentioned by David below ). Windows-1252 is an encoding commonly called "ANSI" (although if you check this Wiki article, you will find out that, according to Microsoft, the term ANSI, used to refer to Windows code pages, is a historical reference, but is currently which continues to persist in the Windows community).

+2
source share

All Articles