2012-07-18 23 views
7

मेरे पास LINQ-to-Entities में 8-बिट "ASCII" वर्णों को संभालने में एक दिलचस्प समस्या है और मुझे उम्मीद है कि कोई मुझे टिप दे सकता है।8-बिट ASCII डेटा के साथ LINQ-to-Entities

मुझे एक SQL सर्वर 2000 डेटाबेस विरासत में मिला है जिसमें कुछ छद्म-एन्क्रिप्टेड कॉलम हैं जहां उन्होंने 0xFF के साथ स्ट्रिंग को XOR'd किया था। पता नहीं क्यों और मुझे पता है कि यह लंगड़ा है, लेकिन वह वहीं है जहां हम अभी हैं।

ये कॉलम एसक्यूएल डेटाटाइप char(7) और char(14) हैं। जब आप XOR 0xFF का उपयोग करते हैं तो आपको हर मामले में 8 वां बिट सेट मिलता है, इसलिए आप गैर-ASCII (माइक्रोसॉफ्ट की परिभाषा के अनुसार) अक्षर के साथ समाप्त होते हैं। यूटीएफ -8 यहां संकेत दिया गया है लेकिन डिकोडिंग गड़बड़ हो जाती है।

  1. क्षेत्र LINQ एक String के रूप में प्रयोग करें:

    मैं इस प्रकार पढ़ सकते हैं और इन तार को डिकोड करने में सक्षम हूँ।

  2. System.Text.Encoding.GetEncoding(1252).GetString()

यह पूरी तरह से काम करता है के साथ डीकोड तार के साथ 0xFF

  • वापसी प्रत्येक बाइट XORing द्वारा एक byte[] का उपयोग कर System.Text.Encoding.GetEncoding(1252).GetBytes()
  • डिकोड प्राप्त करें।

    मेरी समस्या यह है कि मैं LINQ का उपयोग कर SQL सर्वर पर एक ENCODED स्ट्रिंग को वापस नहीं लग सकता।

    मैं मूल रूप से रिवर्स प्रक्रिया अनुसरण कर रही हूं और कर रहा हूँ:

    1. ASCIIEncoding.GetBytes() का उपयोग कर बाइट्स प्राप्त करें। (कोडपेज 1252 के लिए यहां कोई आवश्यकता नहीं है क्योंकि यह एक सीधी स्ट्रिंग है।)
    2. 0xFF के साथ बाइट्स को एन्कोड करें।
    3. GetEncoding(1252).GetString() के साथ एन्कोडेड स्ट्रिंग को वापस करें।

    यदि मैं अपनी स्ट्रिंग को देखता हूं, तो यह वही है जो मैं अपेक्षा करता हूं। लेकिन अगर मैं अपनी इकाई में सामान डालता हूं और SaveChanges() करता हूं तो SQL सर्वर में परिणामी मान हमेशा कुछ लंबाई के "?????" होता है।

    मुझे यकीन है कि मुझे यहां कुछ याद आ रहा है लेकिन मैंने कोशिश की है कि मैं सब कुछ सोच सकता हूं और इसे प्राप्त नहीं कर सकता। अभी के लिए मैं SqlCommand का उपयोग करने के पुराने तरीके से वापस आ गया और एन्कोडेड स्ट्रिंग्स के साथ 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 एन्कोडेड पीडब्ल्यू: जेड?ओ> मूल बाइट्स: 7a 9d 6F 3E डीकोड बाइट्स: 85 62 90 c1 डीकोड पीडब्लू: ख एक

    पासवर्ड वास्तव में है "एबीसीडी"

  • +0

    एसक्यूएल एसक्यूएल प्रोफाइलर का उपयोग कर L2S द्वारा निष्पादित को पकड़ने और इसे पोस्ट करें:

    यहाँ कुछ त्वरित & गंदा कोड है, जो आपकी समस्या का समाधान और प्रदर्शित करने के लिए विभिन्न एन्कोडिंग के साथ कोशिश कर सकते हैं, है। (यह करना बेहद आसान है।) – usr

    +0

    मैं LINQ-to-Entities का उपयोग कर रहा हूं और LINQ-to-SQL नहीं, लेकिन प्रोफाइलर का उपयोग कर SQL को कैप्चर करना एक अच्छा विचार है। मैं इसे स्थापित करूँगा और देख सकता हूं कि यह क्या कहता है। लेकिन मेरा अनुमान है कि यह दिखाएगा कि एसक्यूएल स्टोर करने के लिए जो कहा जा रहा है उसे ठीक से संग्रहित कर रहा है। मुझे सच में विश्वास है कि यह मुद्दा एंटिटी एफडब्ल्यू से एसक्यूएल तक गैर-ASCII वर्णों को मैप करने में है। – user1536209

    +0

    प्रश्न में डेटाबेस के लिए आपका क्या संयोजन है? आप इसे sys.databases से 'SELECT collation_name' नाम से ढूंढ सकते हैं जहां नाम = 'mydatabase''' है। – JamieSee

    उत्तर

    1

    कोड पेज 1252 उपयोग Encoding.GetEncoding(28591) का उपयोग न करें? (आईएसओ -885 9 -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); 
    }