2010-01-15 7 views
9

क्या यह कोड क्लीनर/तेज़ रूप में सरल बनाना संभव है?क्या हम इस स्ट्रिंग एन्कोडिंग कोड को सरल बना सकते हैं

StringBuilder builder = new StringBuilder(); 
var encoding = Encoding.GetEncoding(936); 

// convert the text into a byte array 
byte[] source = Encoding.Unicode.GetBytes(text); 

// convert that byte array to the new codepage. 
byte[] converted = Encoding.Convert(Encoding.Unicode, encoding, source); 

// take multi-byte characters and encode them as separate ascii characters 
foreach (byte b in converted) 
    builder.Append((char)b); 

// return the result 
string result = builder.ToString(); 

बस शब्दों में कहें, यह चीनी अक्षरों जैसे 鄆 के साथ एक स्ट्रिंग लेता है और उन्हें एई में परिवर्तित करता है।

उदाहरण के लिए, दशमलव में चीनी वर्ण हेक्स में 37126 या 0x9106 है।

देखें http://unicodelookup.com/#0x9106/1

एक बाइट सरणी में परिवर्तित, हम मिल [145, 6] (145 * 256 + 6 = 37126)। कोडपेज 936 (सरलीकृत चीनी) में एन्कोड किए जाने पर, हमें [224, 105] मिलता है। यदि हम इस बाइट सरणी को अलग-अलग वर्णों में विभाजित करते हैं, तो हम 224 = e0 = à और 105 = 69 = i यूनिकोड में।

इस प्रकार http://unicodelookup.com/#0x00e0/1 और http://unicodelookup.com/#0x0069/1

देखें, हम एक एन्कोडिंग रूपांतरण कर रहे हैं और यह सुनिश्चित करना है कि हमारे उत्पादन यूनिकोड स्ट्रिंग के सभी पात्रों पर सबसे दो बाइट्स में उपयोग करते हुए दर्शाया जा सकता है।

अपडेट: मुझे इस अंतिम प्रतिनिधित्व की आवश्यकता है क्योंकि यह मेरा रसीद प्रिंटर स्वीकार कर रहा है। इसे हमेशा समझने के लिए मुझे ले लिया! :) चूंकि मैं एन्कोडिंग विशेषज्ञ नहीं हूं, इसलिए मैं सरल या तेज़ कोड ढूंढ रहा हूं, लेकिन आउटपुट एक ही रहना चाहिए।

अद्यतन (क्लीनर संस्करण):

return Encoding.GetEncoding("ISO-8859-1").GetString(Encoding.GetEncoding(936).GetBytes(text)); 
+0

मुझे लगता है कि आपका रसीद प्रिंटर .NET तारों को स्वीकार नहीं करता है, तो आप रसीद प्रिंटर को वास्तव में क्या भेज रहे हैं? पाठ blobs? यदि ऐसा है, तो सभी पाठ तार पर एन्कोड किए गए हैं, इसलिए प्रक्रिया में बाद में कुछ छुपे हुए एन्कोडिंग चलने का एक अच्छा मौका है; "सर्वोत्तम" समाधान को समझना आसान हो सकता है यदि यह स्पष्ट था * कैसे * आप प्रिंटर के साथ संवाद कर रहे हैं। –

+0

मैं .NET के लिए पीओएस का उपयोग कर रहा हूं ... यह स्ट्रिंग स्वीकार करता है और जब तक मैं कोडपेज 1252 में रहता था तब तक यह ठीक काम करता था ... लेकिन 936 के कारण मुद्दों पर पहुंचा, जो इस विशिष्ट प्रिंटर को इन पात्रों को पहचानने के तरीके के कारण है। –

+0

वर्णों की एक सरणी आवंटित करने के लिए अक्सर तेज़ होता है, इसे आवंटित करने के लिए लूप के लिए उपयोग करें, और उसके बाद स्ट्रिंग के कन्स्ट्रक्टर का उपयोग स्ट्रिंग में स्ट्रिंग कैरेक्टर में जोड़ने के बजाय स्ट्रिंग में करने के लिए करें। – Brian

उत्तर

9

ठीक है, एक के लिए, आपको Encoding.Convert पर कॉल करने से पहले "अंतर्निर्मित" स्ट्रिंग प्रस्तुति को बाइट सरणी में परिवर्तित करने की आवश्यकता नहीं है।

तुम सिर्फ कर सकता है:

byte[] converted = Encoding.GetEncoding(936).GetBytes(text); 

तो उस बाइट सरणी जिससे चार मूल्यों सीधे बाइट्स के लिए नक्शे, तुम कर सकते हो से एक तार को फिर से संगठित करने के लिए ...

static string MangleTextForReceiptPrinter(string text) { 
    return new string(
     Encoding.GetEncoding(936) 
      .GetBytes(text) 
      .Select(b => (char) b) 
      .ToArray()); 
} 

मैं wouldn दक्षता के बारे में ज्यादा चिंता मत करो; किसी भी तरह से एक रसीद प्रिंटर पर आप कितने एमबी/सेकंड प्रिंट करने जा रहे हैं?

Joe ने बताया एन्कोडिंग सीधे नक्शे कि बाइट मूल्यों 0-255 अंक कोड करने के लिए नहीं है कि, और यह सदियों पुरानी Latin1 है, जो हमें कार्य करने के लिए छोटा करने के लिए अनुमति देता है है ...

return Encoding.GetEncoding("Latin1").GetString(
      Encoding.GetEncoding(936).GetBytes(text) 
     ); 

तक वैसे, अगर यह एक छोटी गाड़ी विंडोज़-केवल एपीआई है (जो इसे देखता है), तो आप codepage 1252 के बजाय व्यवहार कर रहे हैं (जो लगभग समान है)। आप अपने सिस्टम के साथ क्या कर रहे हैं यह देखने के लिए reflector आज़मा सकते हैं। तार से इसे भेजने से पहले स्ट्रिंग करें।

+0

मेरा अपडेट देखें कि मुझे अंतिम प्रारूप की आवश्यकता क्यों है! –

+0

आपका कोड मेरे लिए काफी अच्छा है! यह सोच रहा था कि क्या एक बल्ट-इन मैंगलिंग फ़ंक्शन था, मुझे पता नहीं था कि यह मेरे लूप से अधिक कुशल होगा। :) –

6

लगभग कुछ भी इस से क्लीनर होगा - क्या तुम सच में यहाँ पाठ कोस रहे हैं, IMO। आप पाठ डेटा के रूप में प्रभावी रूप से अपारदर्शी बाइनरी डेटा (एन्कोडेड टेक्स्ट) का प्रतिनिधित्व करने की कोशिश कर रहे हैं ... इसलिए आपको संभावित रूप से घंटी वर्णों, भागने आदि जैसी चीज़ें मिलेंगी।

टेक्स्ट में अपारदर्शी बाइनरी डेटा एन्कोडिंग का सामान्य तरीका है बेस 64, आप इस्तेमाल कर सकते हैं तो:

return Convert.ToBase64String(Encoding.GetEncoding(936).GetBytes(text)); 

परिणामी पाठ पूरी तरह ASCII, जो बहुत कम संभावना है कि आप परेशानी पैदा करने के लिए किया जाएगा।

संपादित करें: यदि आपको उस आउटपुट की आवश्यकता है, तो मैं दृढ़ता से अनुशंसा करता हूं कि आप इसे स्ट्रिंग के बजाए बाइट सरणी के रूप में प्रस्तुत करें ... इसे उस बिंदु से बाइट सरणी के रूप में पास करें, इसलिए आप लुभाने वाले नहीं हैं इस पर स्ट्रिंग ऑपरेशंस करने के लिए।

+0

+1। मुझे संदेह है कि ओपी का दृष्टिकोण हमेशा उलट नहीं होगा। मतलब है कि आप कुछ डेटा एन्कोड करने में सक्षम होंगे लेकिन इसे सही तरीके से डीकोड नहीं करेंगे। – LBushkin

+0

अंत एन्कोडिंग एक रसीद प्रिंटर द्वारा आवश्यक है जिसे मैं डेटा भेज रहा हूं। –

3

क्या आपके रसीद प्रिंटर में एक एपीआई है जो स्ट्रिंग के बजाय बाइट सरणी स्वीकार करती है? यदि ऐसा है तो आप रसीद प्रिंटर द्वारा उपयोग किए गए एन्कोडिंग का उपयोग करके यूनिकोड स्ट्रिंग से बाइट सरणी तक एक रूपांतरण में कोड को सरल बनाने में सक्षम हो सकते हैं।

इसके अलावा, यदि आप बाइट्स की एक सरणी को एक स्ट्रिंग में कनवर्ट करना चाहते हैं जिसका चरित्र मान बाइट्स के मानों के लिए 1-1 से मेल खाता है, तो आप कोड पेज 28591 उर्फ ​​लैटिन 1 उर्फ ​​आईएसओ -885 9 -1 का उपयोग कर सकते हैं।

अर्थात, और निम्नलिखित

foreach (byte b in converted) 
    builder.Append((char)b); 

string result = builder.ToString(); 

द्वारा प्रतिस्थापित किया जा सकता है:

// All three of the following are equivalent 
// string result = Encoding.GetEncoding(28591).GetString(converted); 
// string result = Encoding.GetEncoding("ISO-8859-1").GetString(converted); 
string result = Encoding.GetEncoding("Latin1").GetString(converted); 

लेटिन 1 एक उपयोगी एन्कोडिंग जब आप एक स्ट्रिंग है, उदा बाइनरी डेटा सांकेतिक शब्दों में बदलना चाहते हैं एक धारावाहिक बंदरगाह के माध्यम से भेजने के लिए।

+0

दुर्भाग्यवश यह नहीं है। अगर ऐसा होता, तो मैंने अपनी गुप्त एन्कोडिंग योजना को समझने की कोशिश में उतना समय व्यतीत नहीं किया होता! –

+0

शायद आंतरिक रूप से यह प्रिंटर को ट्रांसमिशन के लिए यूनिकोड स्ट्रिंग को वापस बाइट सरणी में परिवर्तित कर रहा है, शायद लैटिन 1 जैसे एन्कोडिंग का उपयोग करके। – Joe

+0

अच्छा! मुझे नहीं पता था कि लैटिन -1 में कनवर्ट करना मेरे लूप को बदल देगा। –

संबंधित मुद्दे