Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ-to-Entities with 8-bit ASCII data

I have an interesting issue handling 8-bit "ASCII" characters in LINQ-to-Entities and am hoping someone can give me a tip.

I have inherited a SQL Server 2000 database that has some pseudo-encrypted columns where they just XOR'd the string with 0xFF. Don't know why and I know it's lame but that's where we are now.

These columns are of SQL datatype char(7) and char(14). When you XOR using 0xFF you get the 8th bit set in every case, so you end up with non-ASCII (by Microsoft's definition anyway) characters. UTF-8 seems to be indicated here but the decoding gets messed up.

I am able to read and decode these strings as follows:

  1. Get the field using LINQ as a String.
  2. Get a byte[] using System.Text.Encoding.GetEncoding(1252).GetBytes()
  3. Decode by XORing each byte with 0xFF
  4. Return the decoded string with System.Text.Encoding.GetEncoding(1252).GetString()

This works perfectly.

The problem I'm having is that I can't seem to put an ENCODED string back to SQL Server using LINQ.

I am basically following the reverse process and am doing:

  1. Get the bytes using ASCIIEncoding.GetBytes(). (No need for CodePage 1252 here as this is a straight string.)
  2. Encode the bytes with 0xFF.
  3. Return the encoded string with GetEncoding(1252).GetString().

If I look at my string, it's exactly what I'd expect. But if I stuff that in my entity and do a SaveChanges() the resultant value in SQL Server is always "?????" of some length.

I'm sure I'm missing something here but I've tried everything I can think of and can't get it. For now I just fell back to the old-fashioned way of using a SqlCommand and doing an UPDATE with the encoded strings as SqlParameters. No problem there, works every time.

Thanks in advance for any assistance.


Update:

I tried the suggestion from JamieSee and I'm not even getting good decoding with his method. I have:

    static void Main(string[] args)
    {
        Encoding characterEncoding = Encoding.GetEncoding(28591);

        HCBPWEBEntities ent = new HCBPWEBEntities();

        var encUser =
            (from users in ent.tblEmployer
            where users.ipkEmpId == 357
            select users.sKey).First();

        Console.Out.WriteLine("Original XOR Encoded PW: {0}", encUser.ToString().Trim());

        byte[] originalBytes = (from character in characterEncoding.GetBytes(encUser.ToString().Trim())
                               select (byte)(character)).ToArray();

        Console.Write("Original Bytes:\t");
        foreach (byte b in originalBytes)
        {
            Console.Write("{0:x} ", b);
        }
        Console.WriteLine(String.Empty);

        byte[] decodedBytes = (from character in characterEncoding.GetBytes(encUser.ToString().Trim())
                               select (byte)(character ^ 0xFF)).ToArray();

        Console.Write("Decoded Bytes:\t");
        foreach (byte b in decodedBytes)
        {
            Console.Write("{0:x} ", b);
        }
        Console.WriteLine(String.Empty);

        string decoded = characterEncoding.GetString(decodedBytes);
        Console.WriteLine("Decoded PW: {0}", decoded);

        ent.Dispose();
    }

But the result of that are:

Original XOR Encoded PW: z?o> Original Bytes: 7a 9d 6f 3e Decoded Bytes: 85 62 90 c1 Decoded PW: ?b?A

The password is actually "abcd"

like image 738
jwh20 Avatar asked Jul 18 '12 21:07

jwh20


People also ask

Which is correct about LINQ to Entities?

LINQ to Entities provides Language-Integrated Query (LINQ) support that enables developers to write queries against the Entity Framework conceptual model using Visual Basic or Visual C#. Queries against the Entity Framework are represented by command tree queries, which execute against the object context.

Which is better Entity Framework or LINQ to SQL?

First off, if you're starting a new project, use Entity Framework ("EF") instead of Linq to SQL because it now generates far better SQL (more like Linq to SQL does) and is easier to maintain ("L2S").

What is the difference between LINQ and Entity Framework?

LINQ to SQL allow you to query and modify SQL Server database by using LINQ syntax. Entity framework is a great ORM shipped by Microsoft which allow you to query and modify RDBMS like SQL Server, Oracle, DB2 and MySQL etc. by using LINQ syntax.

What is Entity Framework in C# with example?

Entity Framework (EF) is an object-relational mapper that enables . NET developers to work with relational data using domain-specific objects. It eliminates the need for most of the data-access code that developers usually need to write. Get it: Add this to your project and start taking advantage of this powerful O/RM.


1 Answers

Don't use code page 1252 use Encoding.GetEncoding(28591) (iso-8859-1) or Encoding.GetEncoding(850) (ibm850), either of which gives you 8-bit ASCII-based character sets.

Here's some quick & dirty code, which you can try with different encodings, to demonstrate your issue and the solution:

public static void Main()
{
    Encoding characterEncoding = Encoding.GetEncoding(28591);

    string original = "This is some bogus data to test the problem.";
    Console.WriteLine("Original String: {0}", original);

    Console.Write("Original Bytes: ");
    foreach (byte b in characterEncoding.GetBytes(original))
    {
        Console.Write("{0:x}", b);
    }
    Console.WriteLine();

    byte[] encodedBytes = (from character in characterEncoding.GetBytes(original)
                           select (byte)(character ^ 0xFF)).ToArray();

    Console.Write("Encoded Bytes: ");
    foreach (byte b in encodedBytes)
    {
        Console.Write("{0:x}", b);
    }
    Console.WriteLine();

    string encoded = characterEncoding.GetString(encodedBytes);

    byte[] decodedBytes = (from character in characterEncoding.GetBytes(encoded)
                           select (byte)(character ^ 0xFF)).ToArray();

    Console.Write("Decoded Bytes: ");
    foreach (byte b in decodedBytes)
    {
        Console.Write("{0:x}", b);
    }
    Console.WriteLine();

    string decoded = characterEncoding.GetString(decodedBytes);

    Console.WriteLine("Decoded String: {0}", decoded);
}
like image 168
JamieSee Avatar answered Sep 25 '22 03:09

JamieSee