7

LINQ-to-Entities で 8 ビットの "ASCII" 文字を処理する際に興味深い問題があり、誰かが私にヒントを与えてくれることを願っています。

で文字列を XOR しただけの疑似暗号化列を持つ SQL Server 2000 データベースを継承しました0xFF。理由はわかりませんが、それが不自由であることはわかっていますが、それが私たちが今いるところです。

これらの列は、SQL データ型char(7)およびchar(14). XOR を使用0xFFすると、すべての場合に 8 番目のビットが設定されるため、最終的には非 ASCII (Microsoft の定義による) 文字になります。ここではUTF-8が示されているようですが、デコードがめちゃくちゃになります。

これらの文字列を次のように読み取ってデコードできます。

  1. LINQ を として使用してフィールドを取得しますString
  2. byte[]使用するSystem.Text.Encoding.GetEncoding(1252).GetBytes()
  3. 各バイトを XOR してデコードする0xFF
  4. デコードされた文字列を返しますSystem.Text.Encoding.GetEncoding(1252).GetString()

これは完全に機能します。

私が抱えている問題は、LINQ を使用して ENCODED 文字列を SQL Server に戻すことができないように見えることです。

私は基本的に逆のプロセスに従っていて、やっています:

  1. を使用してバイトを取得しますASCIIEncoding.GetBytes()。(これはストレート文字列なので、ここでは CodePage 1252 は必要ありません。)
  2. でバイトをエンコードします0xFF
  3. でエンコードされた文字列を返しますGetEncoding(1252).GetString()

自分のストリングを見ると、それはまさに私が期待するものです。しかし、それを自分のエンティティに詰め込んで実行するとSaveChanges()、SQL Server の結果の値は常に"?????"ある程度の長さになります。

ここで何かが欠けていると確信していますが、考えられることはすべて試しましたが、取得できません。SqlCommand今のところ、 を使用し、エンコードされた文字列を として UPDATE を実行するという昔ながらの方法に戻りましたSqlParameters。そこに問題はありません、毎回動作します。

ご協力いただきありがとうございます。


アップデート:

JamieSee からの提案を試しましたが、彼の方法ではうまくデコードできません。私は持っている:

    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();
    }

しかし、その結果は次のとおりです。

元の XOR エンコードされた PW: z?o> 元のバイト: 7a 9d 6f 3e デコードされたバイト: 85 62 90 c1 デコードされた PW: ?b?A

パスワードは実際には「abcd」です

4

1 に答える 1

1

コード ページ 1252 を使用しないでください。 Encoding.GetEncoding(28591)(iso-8859-1) またはEncoding.GetEncoding(850)(ibm850) を使用してください。どちらも 8 ビットの ASCII ベースの文字セットを提供します。

問題と解決策を示すために、さまざまなエンコーディングで試すことができる簡単で汚いコードを次に示します。

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);
}
于 2012-07-18T22:24:47.420 に答える