1

I have an encrypt routine in c++, I translate this to C#:

example:

public void main()
{
    string myPwd = "ÖFÖæ6";
    string pwdCoded = XEncrypt.EncryptData_Patch_x_Net(myPwd);
    //Result OK: ÖFÖæ–6
}

public static string EncryptData_Patch_x_Net(string Data)
{
    byte[] bytes = new byte[Data.Length];

    for (int n = 0; n < Data.Length; n++)
    {
        bytes[n] = (byte)Data[n];
    }

    System.Text.Encoding MyEncoding = System.Text.Encoding.Default;
    String MyResult = MyEncoding.GetString(bytes);
    return MyResult;
}

I need to make the inverse routine that made it convert from:

ÖFÖæ–6 to ÖFÖæ6 (notice there's a dash in the left string)

I did this last function, but erroneously performs the encoding

public static string DecryptData_Patch_x_Net(string Data)
{
    byte[] bytes = new byte[Data.Length];

    for (int n = 0; n < Data.Length; n++)
    {
        bytes[n] = (byte)Data[n];
    }

    System.Text.Encoding MyEncoding = System.Text.Encoding.GetEncoding(1252);
    String MyResult = MyEncoding.GetString(bytes);
    return MyResult;
}
J. Steen
  • 15,470
  • 15
  • 56
  • 63
  • 3
    encryption != encoding, decryption != decoding. Anyway, all strings in .Net are unicode. – Jodrell Jan 09 '13 at 14:32
  • I ran your code, and didn't get your expected result ÖFÖæ–6. My default encoding is 1252, as I imagine yours is too. – Jonathan Jan 09 '13 at 14:37
  • You can use the `System.Text.Encoding` namespace to control how `string`s are converted to and from `byte[]`s and `Stream`s but, all strings are unicode. – Jodrell Jan 09 '13 at 14:39
  • @Jonathan the control character in ISO-8859-1 that corresponds to the `–` in Windows-1252, didn't make it to the question. You should try it with `pwd = "ÖFÖæ\u00966"`; – Esailija Jan 09 '13 at 14:40
  • What are you trying to achieve? Discrepencies of coverage between the default code page and Windows-1252 will effect your ability to round trip. – Jodrell Jan 09 '13 at 14:46

2 Answers2

5

This is not encryption and you are seriously complicating what it actually is.

Encoding iso88591 = Encoding.GetEncoding(28591);
Encoding w1252 = Encoding.GetEncoding(1252);

//
string pwd = "ÖFÖæ\u00966"; //The SPA control character will not survice a Stackoverflow post
                            //So I use \u0096 to represent it

string result = w1252.GetString(iso88591.GetBytes(pwd)); //"ÖFÖæ–6"

string original = iso88591.GetString(w1252.GetBytes(result)); //"ÖFÖæ6" with the hidden control character before 6

Console.WriteLine(result == "ÖFÖæ–6"); //True
Console.WriteLine(original == "ÖFÖæ\u00966"); //True
Esailija
  • 138,174
  • 23
  • 272
  • 326
1

Your misnamed ...Encrypt... function makes a fundamental error. You take a string, which treat as a char[] (thats fine), then explicitly cast each char to a byte. That is a narrowing conversion. You'll lose any of the high bits and the ability to round trip more unusual chars. If you look at this question it should help to understand.

You could use this function to get the bytes without loss of information,

static byte[] GetBytes(string str)
{
    byte[] bytes = new byte[str.Length * sizeof(char)];
    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
    return bytes;
}

The byte array will round trip on systems that share endianess.


As Esailija states, becuase its simple and it will explicitly return little endian results, you're better off calling

byte[] Encoding.Unicode.GetBytes(string)

To achieve the same.

Community
  • 1
  • 1
Jodrell
  • 34,946
  • 5
  • 87
  • 124
  • He doesn't lose high bits, but unicode code points that are above 255 (such as `–`, but not `Ö` or `æ` for example). What your function does is a convoluted way of calling `Encoding.Unicode.GetBytes(str)`, that is, encode a string as UTF-16LE. – Esailija Jan 09 '13 at 15:14
  • @Esailija, I agree with you comment. The higher code points are stored in the high bits. If the `chars` are stored with the right Endianess this code is equivalent to `Encoding.Unicode.GetBytes(str)`. – Jodrell Jan 09 '13 at 15:21
  • Ah yes, the internal encoding varies depending on machine. In that case `BitConverter.IsLittleEndian ? Encoding.Unicode.GetBytes(str) : Encoding.BigEndianUnicode.GetBytes(str)` can be used. But his "encryption" doesn't want UTF-16 at all is my point. – Esailija Jan 09 '13 at 15:22
  • @Esailija I'm not sure what the OP wants to be honest. – Jodrell Jan 09 '13 at 15:38