क्या यूटीएफ -16 को हानिकारक माना जाना चाहिए?


432

मैं यह पूछने जा रहा हूं कि क्या संभवतः काफी विवादास्पद प्रश्न है: "क्या सबसे लोकप्रिय एनकोडिंग में से एक, यूटीएफ -16, हानिकारक होना चाहिए?"

मैं यह सवाल क्यों पूछूं?

कितने प्रोग्रामर इस तथ्य से अवगत हैं कि UTF-16 वास्तव में एक चर लंबाई एन्कोडिंग है? इससे मेरा मतलब है कि कोड पॉइंट हैं, जो सरोगेट जोड़े के रूप में दर्शाए जाते हैं, एक से अधिक तत्व लेते हैं।

मुझे पता है; बहुत सारे एप्लिकेशन, फ्रेमवर्क और एपीआई यूटीएफ -16 का उपयोग करते हैं, जैसे कि जावा के स्ट्रिंग, सी # के स्ट्रिंग, विन 32 एपीआई, क्यूटी जीयूआई लाइब्रेरी, आईसीयू यूनिकोड लाइब्रेरी, आदि। हालांकि, इन सभी के साथ, प्रसंस्करण में बहुत सारे बुनियादी कीड़े हैं। BMP से बाहर के वर्ण (दो UTF-16 तत्वों का उपयोग करके वर्णों को कूटबद्ध किया जाना चाहिए)।

उदाहरण के लिए, इनमें से किसी एक अक्षर को संपादित करने का प्रयास करें:

आपके द्वारा इंस्टॉल किए गए फोंट के आधार पर आप कुछ याद कर सकते हैं। ये सभी अक्षर बीएमपी (बेसिक मल्टीलिंगुअल प्लेन) के बाहर हैं। यदि आप इन वर्णों को नहीं देख सकते हैं, तो आप उन्हें यूनिकोड वर्ण संदर्भ में देखने का भी प्रयास कर सकते हैं ।

उदाहरण के लिए, विंडोज में फ़ाइल नाम बनाने की कोशिश करें जिसमें ये वर्ण शामिल हैं; "बैकस्पेस" के साथ इन वर्णों को हटाने की कोशिश करें कि वे यूटीएफ -16 का उपयोग करने वाले विभिन्न अनुप्रयोगों में कैसे व्यवहार करते हैं। मैंने कुछ परीक्षण किए और परिणाम काफी खराब हैं:

  • ओपेरा को उन्हें संपादित करने में समस्या है (बैकस्पेस पर आवश्यक 2 प्रेस हटाएं)
  • नोटपैड उनके साथ सही तरीके से व्यवहार नहीं कर सकता (बैकस्पेस पर आवश्यक 2 प्रेस हटाएं)
  • टूटे हुए विंडो संवादों में फ़ाइल नाम संपादन (बैकस्पेस पर आवश्यक 2 प्रेस हटाएं)
  • सभी qt3 अनुप्रयोग उनके साथ सौदा नहीं कर सकते - एक प्रतीक के बजाय दो खाली वर्ग दिखाएं ।
  • पायथन ऐसे वर्णों को गलत तरीके से एनकोड करता है जब u'X'!=unicode('X','utf-16')BMP के बाहर वर्ण में कुछ प्लेटफार्मों पर सीधे उपयोग किया जाता है ।
  • जब यूटीएफ -16 यूनिकोड स्ट्रिंग्स के साथ अजगर संकलित होता है तो पायथन 2.5 यूनिकोडेटा ऐसे पात्रों पर गुण प्राप्त करने में विफल रहता है।
  • StackOverflow पाठ से इन वर्णों को हटाता हुआ प्रतीत होता है यदि सीधे यूनिकोड वर्णों के रूप में संपादित किया जाता है (इन पात्रों को HTML यूनिकोड एस्केप का उपयोग करके दिखाया गया है)।
  • MaxFength के साथ सीमित होने पर WinForms TextBox अवैध स्ट्रिंग उत्पन्न कर सकती है

ऐसा लगता है कि इस तरह के कीड़े UTF-16 का उपयोग करने वाले कई अनुप्रयोगों में ढूंढना बेहद आसान है।

तो ... क्या आपको लगता है कि UTF-16 को हानिकारक माना जाना चाहिए?


64
वास्तव में सही नहीं है। मैं समझाता हूं, यदि आप "שָׁ" यौगिक चरित्र लिखते हैं जिसमें ",", "ָ" और "vel" होते हैं, तो वेवेल्स, फिर उनमें से प्रत्येक को हटाना तर्कसंगत है, जब आप दबाते हैं तो आप एक कोड-पॉइंट निकाल देते हैं बैकस्पेस "और" डेल "दबाते समय ध्वनि सहित सभी वर्ण हटा दें। लेकिन, आप कभी भी अवैध स्टेट ऑफ़ टेक्स्ट - अवैध कोड पॉइंट नहीं बनाते हैं । इस प्रकार, जब आप बैकस्पेस दबाते हैं और अवैध टेक्स्ट प्राप्त करते हैं तो स्थिति गलत है।

41
सिस्कोपफोन: यदि एक बग को "कई अलग-अलग लोगों द्वारा, कई अलग-अलग लोगों द्वारा" रिपोर्ट किया जाता है, और फिर कुछ साल बाद एक डेवलपर एक देव ब्लॉग पर लिखता है कि "मानो या न मानो, व्यवहार ज्यादातर जानबूझकर है!", फिर (डाल करने के लिए) यह हल्के ढंग से) मुझे लगता है कि यह अब तक का सबसे अच्छा डिज़ाइन निर्णय नहीं है। :-) सिर्फ इसलिए कि यह जानबूझकर है इसका मतलब यह नहीं है कि यह बग नहीं है।

145
महान पद। यूटीएफ -16 वास्तव में "दोनों दुनिया का सबसे खराब" है: यूटीएफ 8 चर-लंबाई है, जिसमें सभी यूनिकोड शामिल हैं, कच्चे कोडपॉइंट्स से और एएससीआईआई को प्रतिबंधित करने के लिए एक परिवर्तन एल्गोरिथ्म की आवश्यकता होती है, और इसमें कोई एंडियननेस मुद्दे नहीं हैं। UTF32 की लंबाई निर्धारित है, इसमें कोई परिवर्तन की आवश्यकता नहीं है, लेकिन अधिक स्थान लेता है और इसमें धीरज के मुद्दे हैं। अब तक अच्छा है, आप क्रमांकन के लिए आंतरिक रूप से UTF32 और UTF8 का उपयोग कर सकते हैं। लेकिन UTF16 का कोई लाभ नहीं है: यह एंडियन-डिपेंडेंट है, यह परिवर्तनशील लंबाई है, इसमें बहुत सारी जगह है, यह ASCII- संगत नहीं है। UTF16 से निपटने के लिए आवश्यक प्रयास को UTF8 पर बेहतर तरीके से खर्च किया जा सकता है।
केरेक एसबी

26
@ इयान: यूटीएफ -8 के पास यूटीएफ -8 के समान कैवेट नहीं हैं। आप UTF-8 में सरोगेट नहीं कर सकते। UTF-8 कुछ ऐसा नहीं है जैसा कि यह नहीं है, लेकिन UTF-16 का उपयोग करने वाले अधिकांश प्रोग्रामर इसका गलत उपयोग कर रहे हैं। मुझे पता है। मैंने उन्हें बार-बार देखा है और बार-बार।
tchrist

18
इसके अलावा, UTF-8 में समस्या नहीं है क्योंकि हर कोई इसे एक चर चौड़ाई एन्कोडिंग के रूप में मानता है। कारण UTF-16 में समस्या है क्योंकि हर कोई इसे एक निश्चित चौड़ाई एन्कोडिंग की तरह मानता है।
क्रिस्टोफर हम्मरस्ट्रॉम

जवाबों:


340

यह एक पुराना उत्तर है। नवीनतम अपडेट के लिए हर जगह UTF-8
देखें ।

राय: हां, यूटीएफ -16 को हानिकारक माना जाना चाहिए । इसका बहुत ही महत्वपूर्ण कारण है क्योंकि कुछ समय पहले एक गलत धारणा थी कि विधुर अब यूसीएस -4 होने जा रहा है।

UTF-8 के "एंग्लो-सेंट्रिज्म" के बावजूद, इसे पाठ के लिए एकमात्र उपयोगी एन्कोडिंग माना जाना चाहिए। कोई यह तर्क दे सकता है कि प्रोग्राम, वेब पेज और एक्सएमएल फाइल, ओएस फाइल नाम और अन्य कंप्यूटर-टू-कंप्यूटर टेक्स्ट इंटरफेस के स्रोत कोड कभी भी मौजूद नहीं होने चाहिए। लेकिन जब वे करते हैं, पाठ केवल मानव पाठकों के लिए नहीं है।

दूसरी ओर, UTF-8 ओवरहेड भुगतान करने के लिए एक छोटी सी कीमत है, जबकि इसके महत्वपूर्ण फायदे हैं। अनजान कोड के साथ संगतता जैसे फायदे जो बस तार के साथ गुजरती हैं char*। यह एक बेहतरीन चीज है। कुछ उपयोगी वर्ण हैं जो UTF-16 में SHORTER हैं क्योंकि वे UTF-8 में हैं।

मुझे विश्वास है कि अन्य सभी एन्कोडिंग अंततः मर जाएंगे। इसमें शामिल है कि एमएस-विंडोज, जावा, आईसीयू, अजगर इसे अपने पसंदीदा के रूप में उपयोग करना बंद कर देते हैं। लंबे शोध और चर्चाओं के बाद, OS API कॉल को छोड़कर, कहीं भी UTF-16 का उपयोग करते हुए मेरी कंपनी प्रतिबंध में विकास सम्मेलनों , और हमारे अनुप्रयोगों में प्रदर्शन के महत्व और इस तथ्य के बावजूद कि हम विंडोज का उपयोग करते हैं। रूपांतरण कार्यों को हमेशा std::stringयूटीएफ -16 में मूल-यूटीएफ 8 के रूप में परिवर्तित करने के लिए विकसित किया गया था , जो स्वयं विंडोज ठीक से समर्थन नहीं करता है

जो लोग कहते हैं कि " जहां जरूरत होती है वहां उपयोग करें ", मैं कहता हूं: हर जगह समान एन्कोडिंग का उपयोग करने का एक बड़ा फायदा है, और मुझे अन्यथा ऐसा करने के लिए कोई पर्याप्त कारण नहीं दिखता है। विशेष रूप से, मुझे लगता है कि wchar_tC ++ में जोड़ना एक गलती थी, और इसलिए C ++ 0x में यूनिकोड के जोड़ हैं। एसटीएल कार्यान्वयन से क्या मांग की जानी चाहिए, हालांकि यह है कि हर std::stringया char*पैरामीटर को यूनिकोड-संगत माना जाएगा।

मैं " आप जो चाहते हैं उसका उपयोग करें " दृष्टिकोण के खिलाफ भी हैं । मुझे ऐसी स्वतंत्रता का कोई कारण नहीं दिखता। पाठ के विषय पर पर्याप्त भ्रम है, जिसके परिणामस्वरूप यह सभी टूटे हुए सॉफ़्टवेयर हैं। ऊपर कहा गया है, मुझे यकीन है कि प्रोग्रामर को अंततः उचित तरीके से UTF-8 पर आम सहमति तक पहुंचना चाहिए। (मैं एक गैर-असिसी भाषी देश से आता हूं और विंडोज पर बड़ा हुआ हूं, इसलिए मुझे आखिरी बार धार्मिक आधार पर UTF-16 पर हमला करने की उम्मीद होगी)।

मैं विंडोज पर पाठ कैसे करता हूं, इसके बारे में अधिक जानकारी साझा करना चाहता हूं, और मैं सभी को संकलन-यूनिकोड शुद्धता, उपयोग में आसानी और कोड के बेहतर बहु-प्लेटफ़ॉर्म की जाँच करने की सलाह देता हूं। सुझाव काफी हद तक अलग-अलग है जो आमतौर पर खिड़कियों पर यूनिकोड का उपयोग करने के उचित तरीके के रूप में अनुशंसित है। फिर भी, इन सिफारिशों के गहन अनुसंधान में एक ही निष्कर्ष निकला। तो यहाँ जाता है:

  • UTF-16 को स्वीकार करने वाले API को आसन्न बिंदु के अलावा किसी अन्य स्थान पर उपयोग न करें wchar_tया न करें std::wstring
  • का प्रयोग न करें _T("")या L""UTF-16 के शाब्दिक (ये IMO मानक से बाहर, UTF-16 प्रतिवाद का एक भाग के रूप में लिया जाना चाहिए)।
  • प्रकार, फ़ंक्शंस या उनके डेरिवेटिव का उपयोग न करें, जो _UNICODEस्थिर के प्रति संवेदनशील हैं , जैसे कि LPTSTRया CreateWindow()
  • फिर भी, _UNICODEहमेशा परिभाषित किया जाता है, जिससे char*कि WinAPI से गुज़रने वाले तारों को चुपचाप संकलित किया जा सके
  • std::stringsऔर char*कहीं भी कार्यक्रम को UTF-8 माना जाता है (यदि अन्यथा नहीं कहा गया है)
  • मेरे सभी तार हैं std::string, हालांकि आप चार * या स्ट्रिंग शाब्दिक पास कर सकते हैं convert(const std::string &)
  • केवल Win32 फ़ंक्शंस का उपयोग करें जो वाइडचर्स ( LPWSTR) स्वीकार करते हैं । जो कभी स्वीकार LPTSTRया LPSTR। इस तरह से पैरामीटर पास करें:

    ::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str())
    

    (नीति नीचे रूपांतरण कार्यों का उपयोग करती है।)

  • MFC स्ट्रिंग्स के साथ:

    CString someoneElse; // something that arrived from MFC. Converted as soon as possible, before passing any further away from the API call:
    
    std::string s = str(boost::format("Hello %s\n") % Convert(someoneElse));
    AfxMessageBox(MfcUtils::Convert(s), _T("Error"), MB_OK);
    
  • विंडोज पर फाइलों, फाइलनामों और फाल्स के साथ काम करना:

    • कभी भी परिवार को तर्क std::stringया const char*नाम न दें fstream। MSVC STL UTF-8 तर्कों का समर्थन नहीं करता है, लेकिन एक गैर-मानक एक्सटेंशन है जिसका उपयोग निम्नानुसार किया जाना चाहिए:
    • इसके साथ std::stringतर्क बदलें :std::wstringUtils::Convert

      std::ifstream ifs(Utils::Convert("hello"),
                        std::ios_base::in |
                        std::ios_base::binary);
      

      जब fstreamपरिवर्तन करने के लिए MSVC का रवैया होगा, तो हमें मैन्युअल रूप से कन्वर्ट को निकालना होगा ।

    • यह कोड मल्टी-प्लेटफ़ॉर्म नहीं है और भविष्य में इसे मैन्युअल रूप से बदलना पड़ सकता है
    • fstreamअधिक जानकारी के लिए यूनिकोड अनुसंधान / चर्चा का मामला 4215 देखें ।
    • गैर-UTF8 सामग्री के साथ कभी भी टेक्स्ट आउटपुट फाइल न बनाएं
    • fopen()RAII / OOD कारणों का उपयोग करने से बचें । यदि आवश्यक हो, _wfopen()ऊपर का उपयोग करें और WinAPI सम्मेलनों।

// For interface to win32 API functions
std::string convert(const std::wstring& str, unsigned int codePage /*= CP_UTF8*/)
{
    // Ask me for implementation..
    ...
}

std::wstring convert(const std::string& str, unsigned int codePage /*= CP_UTF8*/)
{
    // Ask me for implementation..
    ...
}

// Interface to MFC
std::string convert(const CString &mfcString)
{
#ifdef UNICODE
    return Utils::convert(std::wstring(mfcString.GetString()));
#else
    return mfcString.GetString();   // This branch is deprecated.
#endif
}

CString convert(const std::string &s)
{
#ifdef UNICODE
    return CString(Utils::convert(s).c_str());
#else
    Exceptions::Assert(false, "Unicode policy violation. See W569"); // This branch is deprecated as it does not support unicode
    return s.c_str();   
#endif
}

39
मैं सहमत नहीं हो सकता। कई एशियाई भाषाओं के लिए utf16 पर utf16 के फायदे आपके द्वारा किए गए बिंदुओं पर पूरी तरह से हावी हैं। यह आशा है कि जापानी, थाई, चीनी, आदि इस एन्कोडिंग को छोड़ने जा रहे हैं। चारसेट्स के बीच समस्याग्रस्त झड़पें होती हैं, जब अंतर के अलावा, वर्णमाला ज्यादातर समान लगती है। मेरा सुझाव है कि मानकीकरण: तय 7bit: iso-irv-170; 8 बिट चर: utf8; 16 बिट चर: utf16; 32 बिट निर्धारित: ucs4।

82
@Charles: आपके इनपुट के लिए धन्यवाद। सच है, कुछ BMP वर्ण UTF-16 की तुलना में UTF-8 में अधिक लंबे हैं। लेकिन, आइए इसका सामना करते हैं: समस्या बाइट्स में नहीं है जो बीएमपी चीनी अक्षर लेते हैं, लेकिन सॉफ्टवेयर डिजाइन जटिलता जो उत्पन्न होती है। यदि एक चीनी प्रोग्रामर को चर-लंबाई के पात्रों के लिए डिज़ाइन करना होता है, तो ऐसा लगता है कि सिस्टम में अन्य चर की तुलना में UTF-8 अभी भी भुगतान करने के लिए एक छोटी सी कीमत है। वह एक संपीड़न एल्गोरिथ्म के रूप में यूटीएफ -16 का उपयोग कर सकता है यदि अंतरिक्ष इतना महत्वपूर्ण है, लेकिन फिर भी यह एलजेड के लिए कोई मैच नहीं होगा, और एलजेड या अन्य सामान्य संपीड़न के बाद दोनों एक ही आकार और एन्ट्रापी के बारे में लेते हैं।

32
मैं मूल रूप से यह कहता हूं कि वन एन्कोडिंग द्वारा प्रस्तुत सरलीकरण, जो मौजूदा चार * कार्यक्रमों के साथ भी संगत है, और सब कुछ के लिए आज भी सबसे लोकप्रिय है, अकल्पनीय है। यह लगभग अच्छे पुराने "प्लेनटेक्स्ट" दिनों की तरह है। एक नाम के साथ एक फ़ाइल खोलना चाहते हैं? इस बात की परवाह करने की आवश्यकता नहीं है कि आप किस तरह के यूनिकोड कर रहे हैं, आदि। मैं सुझाव देता हूं कि हम, डेवलपर्स, UTF-16 को गंभीर अनुकूलन के बहुत विशेष मामलों में सीमित करते हैं जहां एक छोटा सा प्रदर्शन काम के महीनों के लायक है।

17
जब यूनिक्स के साथ यूटीएफ -8 का उपयोग करना चुनते हैं तो लिनक्स की विशिष्ट आवश्यकता होती है: यूनिक्स के साथ संगतता। विंडोज को इसकी आवश्यकता नहीं थी, और इस तरह जब डेवलपर्स ने यूनिकोड को लागू किया, तो उन्होंने टेक्स्ट को संभालने वाले लगभग सभी कार्यों के यूसीएस -2 संस्करणों को जोड़ा और मल्टीबाइट वाले को केवल यूसीएस -2 में परिवर्तित कर दिया और अन्य को कॉल किया। बाद में UTF-16 के साथ UCS-2 को बदल देता है। दूसरी ओर लिनक्स 8-बिट एनकोडिंग के लिए रखा जाता है और इस प्रकार यूटीएफ -8 का उपयोग किया जाता है, क्योंकि यह उस मामले में उचित विकल्प है।
सिरसा चिरिया

34
@Pavel Radzivilovsky: BTW, आपके लेखन के बारे में "मेरा मानना ​​है कि अन्य सभी एन्कोडिंग अंततः मर जाएंगे। इसमें एमएस-विंडोज, जावा, आईसीयू, अजगर इसे अपने पसंदीदा के रूप में उपयोग करना बंद करते हैं।" और "विशेष रूप से, मुझे लगता है कि wchar_t को C ++ में जोड़ना एक गलती थी, और इसलिए C ++ ऑक्स के लिए यूनिकोड जोड़ हैं।" बहुत भोले हैं या बहुत अभिमानी हैं। और यह लिनक्स पर घर पर किसी को कोडिंग से आ रहा है और जो UTF-8 चार्ट से खुश है। इसे कुंद करने के लिए: ऐसा नहीं होगा
पियरसबल

157

यूनिकोड कोडपॉइंट्स अक्षर नहीं हैं! कभी-कभी वे ग्लिफ़ (दृश्य रूप) भी नहीं होते हैं।

कुछ उदाहरण:

  • रोमन अंक कोडप्वाइंट जैसे "ⅲ"। (एक एकल वर्ण जो "iii" जैसा दिखता है।)
  • "Á" जैसे उच्चारण वाले चरित्र, जिन्हें या तो एक एकल संयुक्त चरित्र "\ u00e1" या एक चरित्र के रूप में दर्शाया जा सकता है और अलग-थलग किया जा सकता है "\ u0061 \ u0301"।
  • ग्रीक लोअरकेस सिग्मा जैसे वर्ण, जिनके मध्य ("and") और शब्द पदों के अंत ("word") के लिए अलग-अलग रूप हैं, लेकिन जिन्हें खोज के लिए समानार्थक शब्द माना जाना चाहिए।
  • यूनिकोड विवेकाधीन हाइफ़न U + 00AD, जो संदर्भ के आधार पर, नेत्रहीन प्रदर्शित नहीं हो सकता है या नहीं, और जिसे अर्थ खोज के लिए अनदेखा किया गया है।

यूनिकोड संपादन अधिकार प्राप्त करने का एकमात्र तरीका एक विशेषज्ञ द्वारा लिखित पुस्तकालय का उपयोग करना है , या एक विशेषज्ञ बनना है और एक स्वयं लिखना है। यदि आप कोडकॉइन की गिनती कर रहे हैं, तो आप पाप की स्थिति में रह रहे हैं।


19
इस। बहुत बहुत यह। UTF-16 समस्या पैदा कर सकता है, लेकिन यहां तक ​​कि पूरे कैन (और इच्छाशक्ति) में UTF-32 का उपयोग करना अभी भी आपको समस्याएँ देता है।
bcat

11
एक चरित्र क्या है? आप एक चरित्र के रूप में एक कोड बिंदु को परिभाषित कर सकते हैं और बहुत अधिक ठीक से प्राप्त कर सकते हैं। यदि आप एक उपयोगकर्ता-दृश्यमान ग्लिफ़ का मतलब है, तो यह कुछ और है।
14 अक्टूबर को tchrist

7
@ स्पेसिस्ट को जगह आवंटित करने के लिए निश्चित है कि परिभाषा ठीक है, लेकिन कुछ और के लिए? इतना नहीं। यदि आप एक संयोजन चरित्र को एकमात्र चरित्र के रूप में संभालते हैं (जैसे कि हटाएं या "पहले एन वर्ण लें" ऑपरेशन) तो आपको अजीब और गलत व्यवहार मिलेगा। यदि कम से कम किसी अन्य के साथ संयुक्त होने पर कोड बिंदु का केवल अर्थ होता है तो आप इसे किसी भी समझदार तरीके से नहीं संभाल सकते।
15:15

6
@ स्पेसर, यह पार्टी के लिए देर से है, लेकिन मुझे उस पर टिप्पणी करनी होगी। कुछ भाषाओं में डायक्ट्रीक्स के संभावित संयोजनों के बहुत बड़े समूह हैं (cf वियतनामी, यानी mđừt sets)। एक वर्णानुक्रम प्रति एक वर्ण के बजाय संयोजन होने से बहुत मदद मिलती है।
अष्टस्रोत

21
शब्दावली पर एक छोटा सा ध्यान दें: कोड पॉइंट्स करते के अनुरूप यूनिकोड वर्ण ; डैनियल यहाँ किस बारे में बात कर रहे हैं, वे उपयोगकर्ता-कथित वर्ण हैं , जो यूनिकोड ग्रैफ़े क्लस्टर के
क्रिस्टोफ़

54

यूनिकोड ट्रांसफॉर्मेशन फॉर्म (यूटीएफ) का उपयोग करने पर अंगूठे का एक सरल नियम है: - भंडारण और संचार के लिए utf-8 - डेटा प्रोसेसिंग के लिए utf-16 - यदि आप जिस प्लेटफ़ॉर्म API का उपयोग करते हैं, आप utf-32 के साथ जा सकते हैं utf-32 (UNIX दुनिया में आम)।

अधिकांश सिस्टम आज utf-16 (विंडोज, मैक ओएस, जावा, .NET, आईसीयू, क्यूटी) का उपयोग करते हैं। इस दस्तावेज़ को भी देखें: http://unicode.org/notes/tn12/

"यूटीएफ -16 हानिकारक" के रूप में वापस, मैं कहूंगा: निश्चित रूप से नहीं।

जो लोग सरोगेट्स से डरते हैं (यह सोचकर कि वे यूनिकोड को एक वैरिएबल-लेंथ एन्कोडिंग में बदल देते हैं) अन्य (रास्ता बड़ा) की जटिलताओं को नहीं समझते हैं जो पात्रों और यूनिकोड कोड के बीच मैपिंग को बहुत जटिल बनाते हैं: वर्ण, संयोजन, विविधता चयनकर्ताओं का संयोजन करना , नियंत्रण वर्ण, आदि।

बस इस श्रृंखला को यहाँ पढ़ें http://www.siao2.com/2009/06/29/9800913.aspx और देखें कि UTF-16 एक आसान समस्या कैसे बन जाती है।


26
कृपया कुछ उदाहरण जोड़ें जहां UNF दुनिया में UTF-32 आम है!
मैक्सक्लेपज़िग

48
नहीं, आप डेटा प्रोसेसिंग के लिए UTF-16 का उपयोग नहीं करना चाहते हैं। गांड में दर्द हो रहा है। इसमें UTF-8 के सभी नुकसान हैं लेकिन इसके कोई भी फायदे नहीं हैं। यूटीएफ -8 और यूटीएफ -32 दोनों स्पष्ट रूप से श्रीमती यूटीएफ -16 के रूप में ज्ञात शातिर हैक से बेहतर हैं, जिसका पहला नाम यूसीएस -2 था।
tchrist

34
मैंने कल ही जावा कोर स्ट्रिंग क्लास के equalsIgnoreCaseतरीके (स्ट्रिंग क्लास में भी अन्य) में एक बग पाया था जो कभी भी नहीं होता था जावा का उपयोग या तो यूटीएफ -8 या यूटीएफ -32 होता था। यूटीएफ -16 का उपयोग करने वाले किसी भी कोड में लाखों सोए हुए बम हैं, और मैं उन्हें बीमार और थका हुआ हूं। यूटीएफ -16 एक शातिर पॉक्स है जो हमारे सॉफ़्टवेयर को हमेशा और हमेशा के लिए कपटी बग्स से ग्रस्त करता है। यह स्पष्ट रूप से हानिकारक है, और इसे पदावनत और प्रतिबंधित किया जाना चाहिए।
14

7
@tchrist वाह तो एक गैर-सरोगेट जागरूक फ़ंक्शन है (क्योंकि यह तब लिखा गया था जब कोई नहीं था और उदास रूप से इस तरह से प्रलेखित किया गया है जिससे इसे अनुकूलित करना असंभव हो जाता है - यह निर्दिष्ट करता है। .UpperCase (char) गलत व्यवहार का परिणाम देगा? आप जानते हैं कि एक पुराने कोड पॉइंट मैप वाला UTF-32 फंक्शन इसे बेहतर तरीके से हैंडल नहीं करेगा? इसके अलावा, संपूर्ण जावा एपीआई विशेष रूप से अच्छी तरह से नहीं सरोगेट्स को संभालता है और यूनिकोड के बारे में अधिक जटिल बिंदुओं को बिल्कुल नहीं - और बाद में उपयोग किए गए एन्कोडिंग से कोई फर्क नहीं पड़ेगा।
वीयू

8
-1: .Substring(1).NET में बिना शर्त सभी गैर-बीएमपी यूनिकोड के लिए समर्थन को तोड़ने का एक तुच्छ उदाहरण है। UTF-16 का उपयोग करने वाली हर चीज में यह समस्या है; इसे निश्चित-चौड़ाई वाले एन्कोडिंग के रूप में व्यवहार करना बहुत आसान है, और आप समस्याओं को बहुत कम देखते हैं। यदि आप यूनिकोड का समर्थन करना चाहते हैं तो यह एक सक्रिय रूप से हानिकारक एन्कोडिंग बनाता है।
रोमन स्टार्कोव

43

हाँ बिल्कुल।

क्यों? यह व्यायाम कोड के साथ करना है

यदि आप टॉम क्रिस्चन द्वारा एक बड़े कॉर्पस पर इन कोडपॉइंट उपयोग के आंकड़ों को देखते हैं, तो आप देखेंगे कि ट्रांस -8 बिट बीएमपी कोडपॉइंट का उपयोग कई आदेशों के लिए किया जाता है यदि गैर-बीएमपी कोडपॉइंट्स से अधिक परिमाण:

 2663710 U+002013 ‹–›  GC=Pd    EN DASH
 1065594 U+0000A0 ‹ ›  GC=Zs    NO-BREAK SPACE
 1009762 U+0000B1 ‹±›  GC=Sm    PLUS-MINUS SIGN
  784139 U+002212 ‹−›  GC=Sm    MINUS SIGN
  602377 U+002003 ‹ ›  GC=Zs    EM SPACE

 544 U+01D49E ‹𝒞›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL C
 450 U+01D4AF ‹𝒯›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL T
 385 U+01D4AE ‹𝒮›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL S
 292 U+01D49F ‹𝒟›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL D
 285 U+01D4B3 ‹𝒳›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL X

TDD डिक्टम लें: "अनटाइड कोड टूटा हुआ कोड है", और इसे "unexercised कोड टूटे हुए कोड" के रूप में रीफ़्रेज़ करें, और सोचें कि प्रोग्रामर को कितनी बार गैर-बीएमपी कोडपॉइंट्स से निपटना पड़ता है।

यूटीएफ -16 से निपटने के लिए एक चर-चौड़ाई एन्कोडिंग के रूप में काम नहीं करने से संबंधित कीड़े यूटीएफ -8 में बराबर बगों की तुलना में किसी का ध्यान नहीं जाने की संभावना है । कुछ प्रोग्रामिंग लैंग्वेज अभी भी आपको UCS-2 के बजाय UTF-16 देने की गारंटी नहीं देती हैं, और कुछ तथाकथित उच्च-स्तरीय प्रोग्रामिंग लैंग्वेज कोड-पॉइंट्स के बजाय कोड यूनिट्स तक पहुंच प्रदान करती हैं (यहां तक ​​कि सी आपको एक्सेस देने वाली हैं कोडपॉइंट यदि आप उपयोग करते हैं wchar_t, भले ही कुछ प्लेटफॉर्म क्या कर सकते हैं)।


16
"यूटीएफ -16 के साथ एक चर-चौड़ाई एन्कोडिंग के रूप में काम नहीं करने से संबंधित कीड़े यूटीएफ -8 में समकक्ष बगों की तुलना में किसी का ध्यान नहीं जाने की अधिक संभावना है।" यह समस्या का मूल है, और इसलिए, सही उत्तर है।
शॉन मैकमिलन

3
यकीनन। यदि आपका UTF-8 हैंडलिंग बोर हो गया है, तो यह तुरंत स्पष्ट हो जाएगा। यदि आपका UTF-8 हैंडलिंग बोर हो गया है, तो आप केवल तभी देखेंगे जब आप असामान्य हान वर्ण या गणित प्रतीकों में डाल देंगे।
मैकेनिकल घोंघा

1
बहुत सच है, लेकिन दूसरी ओर, यदि आप कम लगातार मामलों पर कीड़े खोजने के लिए भाग्य पर निर्भर होना चाहिए, तो इसके लिए इकाई परीक्षण क्या हैं?
मुशीफिल

@ मुसिफिल: तो, जब आपने आखिरी बार गैर-बीएमपी वर्णों के लिए एक इकाई परीक्षण बनाया था?
नवजाल

1
मेरे पहले के बयान पर विस्तार से: यहां तक ​​कि UTF-8 के साथ, आपको यह आश्वासन नहीं दिया जा सकता है कि आपने केवल कुछ कार्य उदाहरणों को देखने के बाद सभी मामलों को कवर किया है। UTF-16 के साथ भी: आपको यह जांचने की आवश्यकता है कि आपका कोड गैर-सरोगेट्स और सरोगेट्स दोनों के साथ काम करता है या नहीं। (कोई यह भी तर्क दे सकता है कि UTF-8 में कम से कम चार प्रमुख मामले हैं जबकि UTF-16 में केवल दो हैं।)
musiphil

40

मेरा सुझाव है कि यूटीएफ -16 को सोचना हानिकारक माना जा सकता है क्योंकि आपको यूनिकोड की अधिक समझ हासिल करने की आवश्यकता है ।

चूँकि मैंने एक व्यक्तिपरक प्रश्न पर अपनी राय प्रस्तुत करने के लिए मुझे नीचा दिखाया है, इसलिए मुझे विस्तार से बताना चाहिए। वास्तव में यह क्या है जो आपको UTF-16 के बारे में परेशान करता है? क्या आप पसंद करेंगे अगर सब कुछ UTF-8 में कूटबद्ध किया गया था? UTF-7? या यूसीएस -4 के बारे में कैसे? निश्चित रूप से कुछ अनुप्रयोगों को वहाँ से बाहर हर वर्ण कोड को संभालने के लिए डिज़ाइन नहीं किया गया है - लेकिन वे आवश्यक हैं, विशेष रूप से आज के वैश्विक सूचना डोमेन में, अंतरराष्ट्रीय सीमाओं के बीच संचार के लिए।

लेकिन वास्तव में, अगर आपको लगता है कि यूटीएफ -16 को हानिकारक माना जाना चाहिए क्योंकि यह भ्रामक है या अनुचित तरीके से लागू किया जा सकता है (यूनिकोड निश्चित रूप से हो सकता है), तो चरित्र एन्कोडिंग की किस विधि को गैर-हानिकारक माना जाएगा?

संपादित करें: स्पष्ट करने के लिए: मानक के अनुचित कार्यान्वयन को मानक की गुणवत्ता का प्रतिबिंब क्यों मानते हैं? जैसा कि अन्य ने बाद में उल्लेख किया है, केवल इसलिए कि कोई एप्लिकेशन अनुचित तरीके से किसी उपकरण का उपयोग करता है, इसका मतलब यह नहीं है कि उपकरण स्वयं दोषपूर्ण है। यदि ऐसा होता, तो हम शायद "var keyword हानिकारक माना जाता", या "थ्रेडिंग हानिकारक माना जाता" जैसी बातें कह सकते थे। मुझे लगता है कि प्रश्न कई प्रोग्रामर को इसे लागू करने और इसका सही उपयोग करने में कठिनाइयों के साथ मानक की गुणवत्ता और प्रकृति को भ्रमित करता है, जो मुझे लगता है कि यूनिकोड के बजाय, यूनिकोड कैसे काम करता है, यह समझने की उनकी कमी से अधिक स्टेम लगता है।


33
-1: कैसे सिर्फ उसे संरक्षण देने के बजाय, अर्टिओम की कुछ आपत्तियों को संबोधित करने के बारे में?

8
BTW: जब मैंने इस लेख को लिखना शुरू किया, तो मैं लगभग लिखना चाहता था "क्या यूनिकोड के सॉफ्टएयर लेख पर जोएल को हानिकारक माना जाना चाहिए" क्योंकि कई गलतियां हैं। उदाहरण के लिए: utf-8 एन्कोडिंग में 4 अक्षर तक होते हैं और 6. नहीं। इसके अलावा यह UCS-2 और UTF-16 के बीच अंतर नहीं करता है जो वास्तव में अलग हैं - और वास्तव में उन समस्याओं का कारण बनता है जिनके बारे में मैं बात करता हूं।

32
इसके अलावा, यह ध्यान दिया जाना चाहिए कि जब जोएल ने वह लेख लिखा था, तो UTF-8 मानक WAS 6 बाइट्स, न कि 4. RFC 3629 ने कई महीनों में मानक को 4 बाइट्स में बदल दिया, जब उसने लेख लिखा। इंटरनेट पर अधिकांश चीजों की तरह, यह एक से अधिक स्रोतों से पढ़ने और अपने स्रोतों की उम्र के बारे में जागरूक होने के लिए भुगतान करता है। लिंक का उद्देश्य "सभी अंत होना" नहीं था, बल्कि एक प्रारंभिक बिंदु था।

7
मैं पिक करूँगा: utf-8 या utf-32 जो हैं: लगभग सभी मामलों में चर लंबाई एन्कोडिंग (BMP सहित) या हमेशा फिक्स्ड एन्कोडिंग।

18
@iconiK: मूर्ख मत बनो। UTF-16 प्रसंस्करण पाठ के लिए वास्तविक मानक नहीं है । मुझे एक प्रोग्रामिंग लैनुज दिखाएं जो टेक्स्ट प्रोसेसिंग के लिए अधिक अनुकूल है, जो कि पर्ल, जिसमें हमेशा (एक दशक से अधिक समय तक) एक अंतर्निहित यूटीएफ -8 प्रतिनिधित्व के साथ सार वर्णों का आंतरिक रूप से उपयोग किया जाता है। इस वजह से, प्रत्येक पर्ल प्रोग्राम स्वचालित रूप से उपयोगकर्ता के बिना सभी यूनिकोड को संभालता है, जिसके पास आइडियोटिक सरोगेट्स के साथ लगातार बंदर होता है। एक स्ट्रिंग की लंबाई कोड पॉइंट में इसकी गिनती होती है, कोड यूनिट नहीं। कुछ और सरासर मूर्खता है जो पीछे की ओर संगतता में डालती है।
tchrist

37

Utf-16 एन्कोडिंग में कुछ भी गलत नहीं है। लेकिन 16-बिट इकाइयों को पात्रों के रूप में व्यवहार करने वाली भाषाओं को संभवतः बुरी तरह से डिजाइन किया जाना चाहिए। एक प्रकार का नाम ' char' जो हमेशा एक चरित्र का प्रतिनिधित्व नहीं करता है वह बहुत भ्रामक है। चूंकि अधिकांश डेवलपर्स एक कोड बिंदु या चरित्र का प्रतिनिधित्व करने के लिए एक चार प्रकार की उम्मीद करेंगे, बहुत अधिक कोड शायद तब टूट जाएगा जब अक्षर beyound BMP के संपर्क में आते हैं।

हालांकि ध्यान दें कि utf-32 का उपयोग करने का यह भी मतलब नहीं है कि प्रत्येक 32-बिट कोड बिंदु हमेशा एक चरित्र का प्रतिनिधित्व करेगा। पात्रों के संयोजन के कारण, एक वास्तविक चरित्र में कई कोड बिंदु शामिल हो सकते हैं। यूनिकोड कभी तुच्छ नहीं है।

Btw। प्लेटफ़ॉर्म और एप्लिकेशन के साथ बग की संभवतः एक ही श्रेणी है जो कि पात्रों को 8-बिट होने की उम्मीद करते हैं, जिन्हें यूटीएफ -8 खिलाया जाता है।


12
जावा के मामले में, यदि आप उनके समयरेखा ( java.com/en/javahistory/timeline.jsp ) को देखते हैं, तो आप देखते हैं कि मुख्य रूप से स्ट्रिंग का विकास हुआ था जबकि यूनिकोड 16 बिट्स था (यह 1996 में बदल गया)। उन्हें गैर बीएमपी कोड बिंदुओं को संभालने की क्षमता पर बोल्ट करना पड़ा, इस प्रकार भ्रम।
कैथी वान स्टोन

10
@ कैथी: वास्तव में सी # के लिए एक बहाना नहीं है, हालांकि। आम तौर पर, मैं मानता हूं कि एक CodePointप्रकार होना चाहिए , एक एकल कोड बिंदु (21 बिट्स), एक CodeUnitप्रकार, एक एकल कोड इकाई (16 बिट्स यूटीएफ -16 के लिए) धारण Characterकरना और एक प्रकार से आदर्श रूप से एक पूर्ण ग्रेपीम का समर्थन करना होगा। लेकिन जो इसे कार्यात्मक रूप से एक समतुल्य बनाता है String...
जॉय

1
यह उत्तर लगभग दो साल पुराना है, लेकिन मैं इस पर टिप्पणी नहीं कर सकता। "एक प्रकार जिसका नाम 'चार' है जो हमेशा एक चरित्र का प्रतिनिधित्व नहीं करता है वह बहुत भ्रामक है।" और फिर भी लोग C में हर समय इसका उपयोग करते हैं और पूर्णांक डेटा को दर्शाने के लिए पसंद करते हैं जिसे एक ही बाइट में संग्रहीत किया जा सकता है।
JAB

और मैंने बहुत सी सी कोड देखी है जो चरित्र एन्कोडिंग को सही ढंग से संभाल नहीं पाती है।
dan04

1
C # का एक अलग बहाना है: इसे विंडोज के लिए डिज़ाइन किया गया था, और विंडोज को UCS-2 पर बनाया गया था (यह बहुत कष्टप्रद है कि आज भी विंडोज एपीआई UTF-8 का समर्थन नहीं कर सकता है)। इसके अलावा, मुझे लगता है कि Microsoft जावा संगतता चाहता था (.NET 1.0 में जावा संगतता पुस्तकालय था, लेकिन उन्होंने जावा समर्थन को बहुत तेज़ी से गिरा दिया - मुझे लगता है कि यह एमएस के खिलाफ सूर्य के मुकदमे के कारण है?)
क्वर्टी

20

मेरी व्यक्तिगत पसंद हमेशा यूटीएफ -8 का उपयोग करना है। यह लगभग सब कुछ के लिए लिनक्स पर मानक है। यह कई विरासत ऐप के साथ पीछे की ओर संगत है। गैर-लैटिन वर्णों बनाम अन्य UTF प्रारूपों के लिए उपयोग किए जाने वाले अतिरिक्त स्थान के संदर्भ में बहुत कम ओवरहेड है, और लैटिन वर्णों के लिए अंतरिक्ष में एक महत्वपूर्ण बचत है। वेब पर, लैटिन भाषाएँ सर्वोच्च शासन करती हैं, और मुझे लगता है कि वे भविष्य के भविष्य के लिए काम करेंगे। और मूल पोस्ट में मुख्य तर्क में से एक को संबोधित करने के लिए: लगभग हर प्रोग्रामर को पता है कि UTF-8 में कभी-कभी इसमें मल्टी-बाइट वर्ण होंगे। हर कोई इसे सही तरीके से नहीं करता है, लेकिन वे आमतौर पर जानते हैं, जो कि यूटीएफ -16 के लिए कहा जा सकता है। लेकिन, ज़ाहिर है, आपको अपने आवेदन के लिए सबसे उपयुक्त चुनने की आवश्यकता है। इसलिए पहले स्थान पर एक से अधिक हैं।


3
यूएमएफ -16 बीएमपी के अंदर किसी भी चीज के लिए सरल है, इसीलिए इसका व्यापक रूप से उपयोग किया जाता है। लेकिन मैं UTF-8 का भी प्रशंसक हूं, इसे बाइट ऑर्डर के साथ कोई समस्या नहीं है, जो इसके लाभ के लिए काम करता है।
मैल्कम

2
सैद्धांतिक रूप से, हाँ। व्यवहार में, इस तरह की बातें हैं, जैसे कि, यूटीएफ -16 बीई, जिसका अर्थ है बिना बीओएम के बड़े एंडियन में यूटीएफ -16। यह कुछ ऐसी चीज नहीं है जिसे मैंने बनाया है, यह एक वास्तविक एन्कोडिंग है जो ID3v2.4 टैग (ID3v2 टैग चूसना, लेकिन दुर्भाग्यवश, व्यापक रूप से उपयोग किया जाता है) में अनुमत है। और इस तरह के मामलों में आपको बाहरी रूप से धीरज को परिभाषित करना होगा, क्योंकि पाठ में ही BOM नहीं है। UTF-8 को हमेशा एक तरह से लिखा जाता है और इसमें ऐसी कोई समस्या नहीं होती है।
मैल्कम

23
नहीं, UTF-16 सरल नहीं है। यह कठिन है। यह आपको गलत तरीके से तय चौड़ाई में भ्रमित और धोखा देता है। इस तरह के सभी कोड टूट गए हैं और सभी मोर्सो क्योंकि आप तब तक नोटिस नहीं करते हैं जब तक कि बहुत देर न हो जाए। बिंदु पर मामला: मुझे अभी कल जावा कोर पुस्तकालयों में एक और बेवकूफ UTF-16 बग मिला, इस बार String.equalsIgnoreCase में, जो UCS-2 ब्रैडगेट बग में छोड़ दिया गया था, और इसलिए 16/17 मान्य यूनिकोड कोड बिंदुओं में विफल रहता है। वह कोड कब तक आसपास रहा है? इसके लिए कोई बहाना नहीं है। यूटीएफ -16 सरासर मूर्खता और दुर्घटना होने की प्रतीक्षा कर रहा है। UTF-16 से रनिंग करें।
tchrist

3
@tchrist एक यह जानने के लिए बहुत ही अनभिज्ञ डेवलपर होना चाहिए कि UTF-16 निश्चित लंबाई नहीं है। यदि आप विकिपीडिया से शुरू करते हैं, तो आप निम्नलिखित को बहुत ऊपर पढ़ेंगे: "यह प्रति कोड बिंदु पर एक या दो 16-बिट कोड इकाइयों के एक चर-लंबाई परिणाम का उत्पादन करता है"। यूनिकोड एफएक्यू वही कहता है: unicode.org/faq//utf_bom.html#utf16-1 । मुझे नहीं पता, अगर यूटीएफ -16 किसी को भी धोखा दे सकता है अगर यह हर जगह लिखा जाए कि यह परिवर्तनशील लंबाई है। इस पद्धति के लिए, इसे यूटीएफ -16 के लिए कभी भी डिज़ाइन नहीं किया गया था और इसे यूनिकोड नहीं माना जाना चाहिए, जितना सरल था।
मैल्कम

2
@tchrist क्या आपके पास अपने आँकड़ों के लिए एक स्रोत है? हालांकि अगर अच्छे प्रोग्रामर एक दुर्लभ, मुझे लगता है कि यह अच्छा है, क्योंकि हम अधिक मूल्यवान हो जाते हैं। :) जावा एपीआई के रूप में, चार-आधारित हिस्से अंततः अपदस्थ हो सकते हैं, लेकिन यह गारंटी नहीं है कि उनका उपयोग नहीं किया जाएगा। और वे निश्चित रूप से संगतता कारणों के लिए हटाया नहीं जाएगा।
मैल्कम

18

खैर, एक एन्कोडिंग है जो निश्चित आकार के प्रतीकों का उपयोग करता है। मैं निश्चित रूप से UTF-32 का मतलब है। लेकिन प्रत्येक प्रतीक के लिए 4 बाइट्स बहुत अधिक बर्बाद जगह है, हम इसे रोजमर्रा की स्थितियों में क्यों इस्तेमाल करेंगे?

मेरे दिमाग में, ज्यादातर समस्याएं इस तथ्य से प्रकट होती हैं कि कुछ सॉफ्टवेयर यूनिकोड मानक के पीछे गिर गए, लेकिन स्थिति को ठीक करने के लिए जल्दी नहीं थे। ओपेरा, विंडोज, पायथन, क्यूटी - ये सभी यूटीएफ -16 व्यापक रूप से ज्ञात होने या यहां तक ​​कि अस्तित्व में आने से पहले दिखाई दिए थे। मैं पुष्टि कर सकता हूं, हालांकि, ओपेरा, विंडोज एक्सप्लोरर और नोटपैड में बीएमपी के बाहर पात्रों के साथ कोई समस्या नहीं है (कम से कम मेरे पीसी पर)। लेकिन वैसे भी, यदि प्रोग्राम सरोगेट जोड़े को नहीं पहचानते हैं, तो वे UTF-16 का उपयोग नहीं करते हैं। ऐसे कार्यक्रमों से निपटने में जो भी समस्याएं आती हैं, उनका यूटीएफ -16 से कोई लेना-देना नहीं है।

हालाँकि, मुझे लगता है कि केवल बीएमपी समर्थन के साथ विरासत सॉफ्टवेयर की समस्याएं कुछ हद तक अतिरंजित हैं। बीएमपी के बाहर वर्ण केवल बहुत ही विशिष्ट मामलों और क्षेत्रों में सामना किए जाते हैं। यूनिकोड के आधिकारिक एफएक्यू के अनुसार , "पूर्वी एशियाई पाठ में भी, सरोगेट जोड़े की घटना औसतन सभी पाठ भंडारण के 1% से कम होनी चाहिए"। बेशक, बीएमपी के बाहर के पात्रों को नजरअंदाज नहीं किया जाना चाहिए क्योंकि एक कार्यक्रम यूनिकोड-अनुरूप नहीं है, लेकिन अधिकांश कार्यक्रम ऐसे पात्रों के साथ काम करने के लिए अभिप्रेत नहीं हैं। इसीलिए अगर वे इसका समर्थन नहीं करते हैं, तो यह अप्रिय है, लेकिन एक आपदा नहीं है।

अब विकल्प पर विचार करते हैं। यदि UTF-16 मौजूद नहीं था, तो हमारे पास एक एन्कोडिंग नहीं होगी जो गैर-ASCII पाठ के लिए अच्छी तरह से अनुकूल है, और UCS-2 के लिए बनाए गए सभी सॉफ़्टवेयर को यूनिकोड-अनुरूप रहने के लिए पूरी तरह से फिर से डिज़ाइन करना होगा। सबसे बाद की संभावना केवल यूनिकोड अपनाने को धीमा कर देगी। इसके अलावा, हम यूसीएस -2 में पाठ के साथ अनुपालन बनाए रखने में सक्षम नहीं होंगे, जैसे यूटीएफ -8 एएससीआईआई के संबंध में करता है।

अब, सभी विरासत मुद्दों को एक तरफ रखकर, एन्कोडिंग के खिलाफ तर्क क्या हैं? मुझे वास्तव में संदेह है कि आजकल डेवलपर्स यह नहीं जानते हैं कि UTF-16 परिवर्तनीय लंबाई है, यह हर जगह विकिपीडिया के साथ घूमते हुए लिखा गया है। UTF-16 को UTF-8 की तुलना में पार्स करना बहुत कम मुश्किल है, अगर किसी ने संभावित समस्या के रूप में जटिलता को इंगित किया। इसके अलावा, यह सोचना गलत है कि केवल UTF-16 में स्ट्रिंग की लंबाई निर्धारित करने के साथ गड़बड़ करना आसान है। यदि आप UTF-8 या UTF-32 का उपयोग करते हैं, तो आपको अभी भी पता होना चाहिए कि एक यूनिकोड कोड बिंदु का मतलब एक वर्ण से नहीं है। इसके अलावा, मुझे नहीं लगता कि एन्कोडिंग के खिलाफ कुछ भी पर्याप्त है।

इसलिए मुझे नहीं लगता कि एन्कोडिंग को हानिकारक माना जाना चाहिए। UTF-16 सादगी और कॉम्पैक्टनेस के बीच एक समझौता है, और जहां जरूरत है, वहां इसका उपयोग करने में कोई बुराई नहीं है । कुछ मामलों में आपको एएससीआईआई के साथ संगत बने रहने की आवश्यकता है और आपको यूटीएफ -8 की आवश्यकता है, कुछ मामलों में आप हान विचारधारा वाले लोगों के साथ काम करना चाहते हैं और यूटीएफ -16 का उपयोग करके अंतरिक्ष का संरक्षण करना चाहते हैं, कुछ मामलों में आपको वर्णों के सार्वभौमिक निरूपण की आवश्यकता होती है, जो एक निश्चित- लंबाई एन्कोडिंग। जो अधिक उपयुक्त है उसका उपयोग करें, बस इसे ठीक से करें।


21
यह एक मिश्रित, एंग्लो केंद्रित दृश्य, मैल्कम है। लगभग "एएससीआईआई संयुक्त राज्य अमेरिका के लिए पर्याप्त है - बाकी दुनिया में हमारे साथ फिट होना चाहिए"।
जोनाथन लेफ़लर

28
वास्तव में मैं रूस से हूं और हर समय (अपने स्वयं के कार्यक्रमों सहित) सिरिलिक का सामना करता हूं, इसलिए मुझे नहीं लगता कि मेरे पास एंग्लो-केंद्रित दृश्य है। :) ASCII का उल्लेख करना काफी उचित नहीं है, क्योंकि यह यूनिकोड नहीं है और विशिष्ट वर्णों का समर्थन नहीं करता है। UTF-8, UTF-16, UTF-32 बहुत ही अंतरराष्ट्रीय चरित्र सेट का समर्थन करते हैं, वे सिर्फ अपने विशिष्ट क्षेत्रों में उपयोग के लिए हैं। और यह बिल्कुल मेरी बात है: यदि आप ज्यादातर अंग्रेजी का उपयोग करते हैं, तो यूटीएफ -8 का उपयोग करें, यदि आप ज्यादातर सिरिलिक का उपयोग करते हैं, तो यूटीएफ -16 का उपयोग करें, यदि आप प्राचीन भाषाओं का उपयोग करते हैं, तो यूटीएफ -32 का उपयोग करें। काफी सरल।
मैल्कम

16
"सच नहीं है, जापानी, चीनी या अरबी जैसी एशियाई स्क्रिप्ट भी बीएमपी से संबंधित हैं। बीएमपी वास्तव में बहुत बड़ी है और निश्चित रूप से आजकल उपयोग की जाने वाली सभी लिपियों को शामिल करने के लिए पर्याप्त बड़ी है" यह सब इतना गलत है। BMP में 0xFFFF वर्ण (65536) हैं। अकेले चीनी से ज्यादा है। चीनी मानकों (जीबी 18030) से अधिक है। यूनिकोड 5.1 पहले से ही 100,000 से अधिक वर्णों को आवंटित करता है।

12
@ मार्कोम: "बीएमपी ही वास्तव में बहुत बड़ी है और निश्चित रूप से आजकल उपयोग की जाने वाली सभी लिपियों को शामिल करने के लिए पर्याप्त बड़ी है" सच नहीं है। इस बिंदु पर यूनिकोड पहले से ही 100K वर्णों के बारे में आवंटित करता है, जिस तरह से BMP से अधिक चल सकता है। बीएमपी के बाहर चीनी पात्रों की बड़ी संख्या है। और उनमें से कुछ की आवश्यकता GB-18030 (अनिवार्य चीनी मानक) है। अन्य (गैर-अनिवार्य) जापानी और कोरियाई मानकों द्वारा आवश्यक हैं। इसलिए यदि आप उन बाजारों में कुछ भी बेचने की कोशिश करते हैं, तो आपको बीएमपी समर्थन से परे की आवश्यकता है।

8
कुछ भी जो यूटीएफ -16 का उपयोग करता है, लेकिन केवल संकीर्ण बीएमपी पात्रों को संभाल सकता है, वास्तव में यूटीएफ -16 का उपयोग नहीं कर रहा है। यह छोटी गाड़ी है और टूटी हुई है। ओपी का आधार ध्वनि है: UTF-16 हानिकारक है, क्योंकि यह भोले लोगों को टूटे हुए कोड को लिखने की ओर ले जाता है। या तो आप यूनिकोड पाठ को संभाल सकते हैं, या आप नहीं कर सकते। यदि आप नहीं कर सकते हैं, तो आप एक सबसेट चुन रहे हैं, जो कि ASCII- केवल टेक्स्ट प्रोसेसिंग की तरह ही बेवकूफ है।
tchrist

16

विशेष रूप से पूर्वी एशियाई भाषाओं में विंडोज के अंतर्राष्ट्रीयकरण के काम ने मुझे भ्रष्ट कर दिया है, लेकिन मैं स्ट्रिंग्स के आंतरिक-टू-द-प्रोग्राम प्रतिनिधित्व के लिए UTF-16 की ओर झुकता हूं, और नेटवर्क के लिए UTF-8 या प्लेनटेक्स्ट जैसे दस्तावेजों के फ़ाइल भंडारण के लिए। यूटीएफ -16 को आमतौर पर विंडोज पर तेजी से संसाधित किया जा सकता है, हालांकि, यह विंडोज़ में यूटीएफ -16 का उपयोग करने का प्राथमिक लाभ है।

UTF-16 में छलांग लगाने से नाटकीय रूप से अंतरराष्ट्रीय पाठ को संभालने वाले औसत उत्पादों की पर्याप्तता में सुधार हुआ। केवल कुछ संकीर्ण मामले हैं जब सरोगेट जोड़े पर विचार किया जाना चाहिए (विलोपन, सम्मिलन, और लाइन ब्रेकिंग, मूल रूप से) और औसत-मामला ज्यादातर सीधे पास-थ्रू है। और जेआईएस वेरिएंट जैसे पहले के एन्कोडिंग के विपरीत, यूटीएफ -16 जोड़े को बहुत संकीर्ण सीमा तक सीमित करता है, इसलिए चेक वास्तव में त्वरित है और आगे और पीछे काम करता है।

दी, यह लगभग सही ढंग से इनकोडिंग UTF-8 में भी जल्दी है। लेकिन कई टूटे हुए यूटीएफ -8 अनुप्रयोग भी हैं जो गलत तरीके से सरोगेट जोड़े को दो यूटीएफ -8 अनुक्रमों के रूप में एन्कोड करते हैं। तो UTF-8 उद्धार की गारंटी नहीं देता है।

IE सरोगेट जोड़े को 2000 या उसके बाद से यथोचित रूप से संभालता है, भले ही यह आम तौर पर उन्हें UTF-8 पृष्ठों से आंतरिक UTF-16 प्रतिनिधित्व में परिवर्तित कर रहा है; मुझे पूरा यकीन है कि फ़ायरफ़ॉक्स को यह सही भी मिल गया है, इसलिए मैं वास्तव में परवाह नहीं करता कि ओपेरा क्या करता है।

UTF-32 (उर्फ UCS4) ज्यादातर अनुप्रयोगों के लिए व्यर्थ है क्योंकि यह इतनी जगह की मांग है, इसलिए यह बहुत ज्यादा नॉनस्टार्टर है।


6
मुझे UTF-8 और सरोगेट जोड़े पर आपकी टिप्पणी काफी पसंद नहीं आई। सरोगेट जोड़े केवल एक अवधारणा है जो UTF-16 एन्कोडिंग में सार्थक है, है ना? शायद कोड जो UTF-16 एन्कोडिंग से सीधे UTF-8 एन्कोडिंग में परिवर्तित होता है, यह गलत हो सकता है, और उस स्थिति में, समस्या UTF-16 को गलत तरीके से पढ़ रही है, UTF-8 को नहीं लिख रहा है। क्या वह सही है?
क्रेग मैकक्वीन

11
जेसन के बारे में जो बात हो रही है वह सॉफ्टवेयर है जो जानबूझकर UTF-8 को लागू करता है: एक सरोगेट जोड़ी बनाएं, फिर UTF-8 प्रत्येक आधे को अलग से एनकोड करें। उस एन्कोडिंग का सही नाम CESU-8 है, लेकिन Oracle (उदा) इसे UTF-8 के रूप में गलत बताता है। जावा ऑब्जेक्ट सीरियलाइजेशन के लिए एक समान योजना का उपयोग करता है, लेकिन यह स्पष्ट रूप से "संशोधित यूटीएफ -8" के रूप में और केवल आंतरिक उपयोग के लिए प्रलेखित है। (अब, अगर हम सिर्फ लोगों को उस दस्तावेज़ को पढ़ सकते हैं और DataInputStream # readUTF () और DataOutputStream # writeUTF () अनुचित तरीके से उपयोग करना बंद कर सकते हैं

AFAIK, UTF-32 अभी भी चर लंबाई एन्कोडिंग है, और यूसीएस 4 के बराबर नहीं है जो कोड बिंदु की विशिष्ट सीमा है।
Eonil

@ यूनील, यूटीएफ -32 केवल यूसीएस 4 से अलग होगा, अगर हमारे पास यूनिकोड मानक है जो यूसीएस 5 या बड़े जैसे कुछ को पेश करता है।
जेसनट्र्यू

@JasonTrue फिर भी, केवल परिणाम समान रूप से समान हैं, डिजाइन द्वारा गारंटी नहीं। 32-बिट मेमोरी एड्रेसिंग, वाई 2 के, यूटीएफ 16 / यूसीएस 2 में भी यही हुआ था। या क्या हमारे पास उस समानता की कोई गारंटी है? अगर हमारे पास है, तो मैं ख़ुशी से उपयोग करूँगा। लेकिन मैं एक संभावित टूटने वाला कोड नहीं लिखना चाहता । मैं एक चरित्र स्तर कोड लिख रहा हूं, और UTF के बीच ट्रांसकोड करने के लिए एक गारंटीकृत तरीके की कमी <-> कोड बिंदु मुझे बहुत परेशान कर रहा है।
Eonil

16

UTF-8 निश्चित रूप से जाने के लिए रास्ता है, संभवतः एल्गोरिदम में आंतरिक उपयोग के लिए UTF-32 के साथ है जिसमें उच्च प्रदर्शन यादृच्छिक अभिगम की आवश्यकता होती है (लेकिन यह संयोजन को अनदेखा करता है)।

UTF-16 और UTF-32 (साथ ही उनके LE / BE वेरिएंट) धीरज के मुद्दों से ग्रस्त हैं, इसलिए उन्हें कभी भी बाहरी रूप से उपयोग नहीं किया जाना चाहिए।


9
UTF-8 के साथ लगातार समय का उपयोग संभव है, कोड बिंदुओं के बजाय केवल कोड इकाइयों का उपयोग करें। हो सकता है कि आपको वास्तविक रैंडम कोड पॉइंट एक्सेस की आवश्यकता हो, लेकिन मैंने कभी उपयोग का मामला नहीं देखा है, और आप इसके बजाय यादृच्छिक ग्रैफेम क्लस्टर एक्सेस चाहते हैं।

15

UTF-16? निश्चित रूप से हानिकारक है। बस मेरे यहाँ नमक के दाने, लेकिन एक कार्यक्रम में पाठ के लिए तीन स्वीकार्य एनकोडिंग हैं:

  • ASCII: जब निम्न स्तर की चीजों (जैसे: माइक्रोकंट्रोलर्स) के साथ काम करते हैं जो कुछ भी बेहतर नहीं कर सकते
  • UTF8: फाइलों जैसे फिक्स्ड-चौड़ाई मीडिया में भंडारण
  • पूर्णांक कोडपॉइंट्स ("CP"?): सबसे बड़ा पूर्णांकों की एक सरणी जो आपकी प्रोग्रामिंग भाषा और प्लेटफ़ॉर्म के लिए सुविधाजनक है (कम रिसोर्स की सीमा में एएससीआईआई के लिए निर्णय लेता है)। पुराने कंप्यूटरों पर int32 और 64-बिट एड्रेसिंग के साथ किसी भी चीज पर int64 होना चाहिए।

  • स्पष्ट रूप से विरासत कोड के लिए इंटरफेस का उपयोग पुराने कोड को सही बनाने के लिए एन्कोडिंग की आवश्यकता है।


4
@ साइमन बुचन, U+10ffffअधिकतम खिड़की से बाहर चला जाएगा जब (नहीं तो) वे कोडपॉइंट से बाहर निकलते हैं। उस ने कहा, गति के लिए एक p64 प्रणाली पर int32 का उपयोग करना संभवत: सुरक्षित है, क्योंकि मुझे संदेह है कि वे U+ffffffffइससे पहले कि आप 2050 के आसपास 128 बिट सिस्टम के लिए अपने कोड को फिर से लिखने के लिए मजबूर हो जाएँगे। (कि "सबसे बड़ी int का उपयोग करें" की बात है सुविधाजनक है "के रूप में" सबसे बड़ा उपलब्ध "(जो शायद int256 या bignums या कुछ और होगा) के विपरीत।)
डेविड एक्स

1
@ डेविड: यूनिकोड 5.2 ने 107,361 कोडपॉइंट्स एन्कोड किए। 867,169 अप्रयुक्त कोडपॉइंट हैं। "जब" बस मूर्खतापूर्ण है। यूनिकोड कोडपॉइंट को 0 से 0x10FFFF तक की संख्या के रूप में परिभाषित किया गया है, एक संपत्ति जो UTF-16 पर निर्भर करती है। (इसके अलावा 2050 128 बिट सिस्टम के लिए अनुमान से बहुत कम लगता है जब 64-बिट सिस्टम इंटरनेट का संपूर्ण पता अंतरिक्ष में पकड़ सकता है।)

3
@ डेविड: आपका "जब" यूनिकोड कोडपॉइंट्स से बाहर निकलने की बात कर रहा था, न कि 128-बिट स्विच जो कि, हाँ, अगली कुछ शताब्दियों में होगा। स्मृति के विपरीत, पात्रों की कोई घातीय वृद्धि नहीं होती है, इसलिए यूनिकोड कंसोर्टियम ने विशेष रूप से गारंटी दी है कि वे ऊपर दिए गए कोड बिंदु को कभी भी आवंटित नहीं करेंगे U+10FFFF। यह वास्तव में 21 बिट जब उन स्थितियों में से एक है है किसी को भी के लिए पर्याप्त।

10
@Simon बुकान: कम से कम पहले संपर्क तक। :)

3
यूनिकोड गारंटी देता था कि U + FFFF के ऊपर भी कोई कोड बिंदु नहीं होगा।
शैनन सेवरेंस

13

यूनिकोड कोड को 0x10FFFF (1,114,112 कोड) तक परिभाषित करता है, स्ट्रिंग्स / फ़ाइल नामों आदि से निपटने वाले बहुभाषी वातावरण में चल रहे सभी अनुप्रयोगों को सही ढंग से संभालना चाहिए।

Utf-16 : केवल 1,112,064 कोड शामिल हैं। हालांकि यूनिकोड के अंत में वे विमान 15-16 (निजी उपयोग क्षेत्र) से हैं। यह भविष्य में यूटीएफ -16 अवधारणा को तोड़ने के अलावा और नहीं बढ़ सकता है ।

Utf-8 : सैद्धांतिक रूप से 2,216,757,376 कोड शामिल हैं। यूनिकोड कोड की वर्तमान सीमा को अधिकतम 4 बाइट अनुक्रम द्वारा दर्शाया जा सकता है। यह बाइट ऑर्डर की समस्या से ग्रस्त नहीं है, यह आस्की के साथ "संगत" है।

Utf-32 : सैद्धांतिक रूप से 2 ^ 32 = 4,294,967,296 कोड शामिल हैं। वर्तमान में यह परिवर्तनीय लंबाई एन्कोडेड नहीं है और शायद भविष्य में नहीं होगी।

वे तथ्य स्वयं व्याख्यात्मक हैं। मैं यूटीएफ -16 के सामान्य उपयोग की वकालत नहीं करता । यह परिवर्तनीय लंबाई एन्कोडेड है (इसे इंडेक्स द्वारा एक्सेस नहीं किया जा सकता है), इसमें वर्तमान में भी पूरे यूनिकोड रेंज को कवर करने की समस्या है , बाइट ऑर्डर को संभाला जाना चाहिए, आदि। मुझे कोई फायदा नहीं दिखाई दे रहा है सिवाय इसके कि यह विंडोज़ और कुछ में मूल रूप से उपयोग किया जाता है। अन्य स्थान। भले ही मल्टी-प्लेटफ़ॉर्म कोड लिखते समय, शायद यूटीएफ -8 का मूल रूप से उपयोग करना और प्लेटफ़ॉर्म आश्रित तरीके से अंतिम बिंदुओं पर ही रूपांतरण करना संभव है (जैसा कि पहले ही सुझाव दिया गया है)। जब सूचकांक द्वारा प्रत्यक्ष पहुंच आवश्यक है और स्मृति कोई समस्या नहीं है, तो यूटीएफ -32 का उपयोग किया जाना चाहिए।

मुख्य समस्या यह है कि विंडोज यूनिकोड = यूटीएफ -16 के साथ काम करने वाले कई प्रोग्रामर इस तथ्य को जानते या अनदेखा नहीं करते हैं कि यह चर लंबाई एन्कोडेड है।

जिस तरह से यह आमतौर पर * निक्स प्लेटफॉर्म में बहुत अच्छा है, सी स्ट्रिंग्स (चार *) की व्याख्या यूटीएफ -8 एन्कोडेड के रूप में की गई, विस्तृत सी स्ट्रिंग्स (wchar_t *) की व्याख्या यूटीएफ -32 के रूप में की गई ।


7
नोट: यूटीएफ -16 सभी यूनिकोड को शामिल करता है क्योंकि यूनिकोड कंसोर्टियम ने तय किया कि 10 एफएफएफ यूनिकोड की टॉप रेंज है और यूटीएफ -8 अधिकतम 4 बाइट्स लंबाई को परिभाषित करता है और वैध कोड पॉइंट रेंज से स्पष्ट रूप से बाहर की गई रेंज 0xD800-0xxFFFF है और इस रेंज का उपयोग निर्माण के लिए किया जाता है। सरोगेट जोड़े। तो किसी भी मान्य यूनिकोड पाठ को इनमें से प्रत्येक एन्कोडिंग के साथ दर्शाया जा सकता है। भविष्य में बढ़ने के बारे में भी। ऐसा नहीं लगता है कि 1 मिलियन कोड अंक किसी भी भविष्य में पर्याप्त नहीं होंगे।

7
@ केरैक: गलत: यूसीएस -2 एक वैध यूनिकोड एन्कोडिंग नहीं है। सभी UTF- * परिभाषा के अनुसार एनकोडिंग किसी भी यूनिकोड कोड बिंदु का प्रतिनिधित्व कर सकती है जो इंटरचेंज के लिए कानूनी है। UCS-2 इससे बहुत कम प्रतिनिधित्व कर सकता है, साथ ही कुछ और भी। पुनरावृत्ति: यूसीएस -2 एक वैध यूनिकोड एन्कोडिंग नहीं है, एएससीआईआई की तुलना में कोई भी मोर्सो है।
tchrist

1
"मैं यूटीएफ -8 के सामान्य उपयोग की वकालत नहीं करता । यह चर लंबाई एन्कोडेड है (सूचकांक द्वारा पहुँचा नहीं जा सकता)"
इयान बोयड

9
@ इयान बॉयड, एक स्ट्रिंग के अलग-अलग चरित्र को एक यादृच्छिक एक्सेस पैटर्न में एक्सेस करने की आवश्यकता अविश्वसनीय रूप से अतिरंजित है। यह मैट्रिक्स के पात्रों के विकर्ण की गणना करने के लिए सामान्य के बारे में है, जो सुपर दुर्लभ है। स्ट्रिंग्स को हमेशा क्रमिक रूप से संसाधित किया जाता है, और चूंकि UTF-8 char N + 1 को एक्सेस करने के बाद आप UTF-8 char N O (1) पर हैं, इसलिए कोई समस्या नहीं है। तार की बेतरतीब पहुँच बनाने की बहुत कम जरूरत है। चाहे आपको लगता है कि यह UTF-8 के बजाय UTF-32 में जाने के लिए भंडारण स्थान के लायक है, आपकी अपनी राय है, लेकिन मेरे लिए, यह पूरी तरह से एक गैर-मुद्दा है।
tchrist

2
@tchrist, मैं आपको यह बताता हूं कि यदि आप रिवर्स अनुक्रम को "अनुक्रमिक" के रूप में शामिल करते हैं तो आप हमेशा स्ट्रिंग को क्रमिक रूप से संसाधित करते हैं और यह जानते हैं कि स्ट्रिंग के अनुगामी छोर की ज्ञात स्ट्रिंग से थोड़ा आगे की तुलना करें। दो बहुत ही सामान्य परिदृश्य स्ट्रिंग्स के अंत से व्हाट्सएप को काट रहे हैं और एक पथ के अंत में फ़ाइल एक्सटेंशन की जांच कर रहे हैं।
एंडी डेंट

11

इसे सूची में जोड़ें:

प्रस्तुत परिदृश्य सरल है (और भी सरल के रूप में मैं इसे यहां पेश करूंगा क्योंकि यह मूल रूप से था!): 1.A WinForms TextBox एक फॉर्म पर बैठता है, खाली। इसमें अधिकतम मैक्सिमम सेट 20 है

2. उपयोगकर्ता पाठ बॉक्स में टाइप करता है, या हो सकता है कि उसमें पाठ चिपकाता है।

3. कोई फर्क नहीं पड़ता कि आप टेक्स्टबॉक्स में क्या लिखते हैं या पेस्ट करते हैं, आप 20 तक सीमित हैं, हालांकि यह 20 से परे पाठ पर सहानुभूतिपूर्वक बीप करेगा (यहां YMMV; मैंने मुझे उस प्रभाव को देने के लिए अपनी ध्वनि योजना बदल दी!)।

4. एक रोमांचक रोमांच शुरू करने के लिए पाठ का छोटा पैकेट फिर कहीं और भेजा जाता है।

अब यह एक आसान परिदृश्य है, और कोई भी इसे खाली समय में लिख सकता है। मैंने सिर्फ WinForms का उपयोग करते हुए इसे कई प्रोग्रामिंग भाषाओं में लिखा था, क्योंकि मैं बोर हो गया था और इससे पहले कभी कोशिश नहीं की। और कई वास्तविक भाषाओं में पाठ के साथ क्योंकि मैं उस तरह से तार-तार हो गया हूं और पूरे फ्रैकिंग ब्रह्मांड में संभवतः किसी की तुलना में अधिक कीबोर्ड लेआउट हैं।

मैंने बोरियत को ठीक करने में मदद करने के लिए मैजिक कारपेट राइड का नाम भी दिया ।

यह काम नहीं किया, इसके लायक क्या है।

इसलिए इसके बजाय, मैंने अपने मैजिक कार्पेट राइड फॉर्म में निम्नलिखित 20 अक्षर दर्ज किए :

0123401234012340123 𠀀

उह ओह।

वह अंतिम पात्र U + 20000 है, यूनिकोड का पहला एक्सटेंशन B विचारधारा (उर्फ U + d840 U + dc00, अपने करीबी दोस्तों के लिए जिसे वह शर्मिंदा नहीं है, जैसा कि वह सामने था)।

यहां छवि विवरण दर्ज करें

और अब हमारे पास एक गेंद का खेल है।

क्योंकि जब TextBox.MaxLength के बारे में बात करता है

हो जाता है या अधिकतम वर्ण सेट करता है जिन्हें पाठ बॉक्स में मैन्युअल रूप से दर्ज किया जा सकता है।

इसका वास्तव में मतलब क्या है

अधिकतम संख्या में UTF-16 LE कोड इकाइयाँ बनती या सेट होती हैं जिन्हें मैन्युअल रूप से टेक्स्ट बॉक्स में दर्ज किया जा सकता है और यह किसी भी स्ट्रिंग से जीवित बकवास को निर्दयतापूर्वक काट देगा जो भाषाई चरित्र के साथ cutesy गेम खेलने की कोशिश करता है जो केवल किसी के रूप में जुनूनी नहीं है कि कपलान साथी आपत्तिजनक लगेगा (गीज़ उसे और बाहर निकलने की ज़रूरत है!)।

मैं कोशिश करूँगा और दस्तावेज़ को अपडेट करने के बारे में देखूंगा ....
नियमित रूप से पाठक जो मेरे यूसीएस -2 को यूटीएफ -16 श्रृंखला में याद करते हैं, टेक्स्टबॉक्स की सरल धारणा के साथ मेरी नाखुशी को ध्यान में रखेंगेमैक् लक्स और कैसे इसे कम से कम इस मामले को संभालना चाहिए जहाँ इसका ड्रैकियन व्यवहार एक अवैध अनुक्रम बनाता है, एक .Net फ्रेमवर्क के अन्य भागों को फेंक सकता है

  • System.Text.EncoderFallbackException: यूनिकोड वर्ण \ uD850 को अनुक्रमणिका 0 में निर्दिष्ट कोड पृष्ठ पर अनुवाद करने में असमर्थ। *

अपवाद अगर आप इस स्ट्रिंग को .Net फ्रेमवर्क में कहीं और पास करते हैं (जैसा कि मेरे सहयोगी डैन थॉम्पसन कर रहे थे)।

अब ठीक है, शायद यूटीएफ -16 श्रृंखला के लिए पूर्ण यूसीएस -2 कई की पहुंच से बाहर है।
लेकिन यह उम्मीद करना उचित नहीं है कि TextBox.Text एक System.String का उत्पादन नहीं करेगा कि .Net फ्रेमवर्क का एक और टुकड़ा फेंकने का कारण नहीं होगा? मेरा मतलब है, ऐसा नहीं है कि नियंत्रण पर कुछ घटना के रूप में एक मौका है जो आपको आगामी ट्रंकेशन के बारे में बताता है जहां आप आसानी से होशियार सत्यापन - सत्यापन को जोड़ सकते हैं जो नियंत्रण खुद करने में कोई आपत्ति नहीं करता है। मैं इतना कहना चाहूंगा कि यह गुंडा नियंत्रण एक सुरक्षा अनुबंध को तोड़ रहा है, जो सुरक्षा समस्याओं को भी जन्म दे सकता है यदि आप किसी एप्लिकेशन को सेवा से वंचित करने के लिए एक अनपेक्षित अपवाद के रूप में अप्रत्याशित अपवाद पैदा कर सकते हैं। किसी भी WinForms प्रक्रिया या विधि या एल्गोरिथ्म या तकनीक को अमान्य परिणाम क्यों उत्पन्न करना चाहिए?

स्रोत: माइकल एस। कपलान MSDN ब्लॉग


धन्यवाद, बहुत अच्छी लिंक! मैंने इसे प्रश्न सूची की समस्याओं की सूची में जोड़ दिया है।

9

मैं जरूरी नहीं कहूंगा कि UTF-16 हानिकारक है। यह सुरुचिपूर्ण नहीं है, लेकिन यह UCS-2 के साथ पश्चगामी संगतता के अपने उद्देश्य को पूरा करता है, जैसे GB18030 GB2312 के साथ करता है, और UTF-8 ASCII के साथ करता है।

लेकिन Microsoft और Sun ने 16-बिट वर्णों वाले विशाल APIs के निर्माण के बाद, यूनिकोड की संरचना में मध्य-क्रम में एक मूलभूत परिवर्तन किया, यह हानिकारक था। परिवर्तन की जागरूकता फैलाने में विफलता अधिक हानिकारक थी।


8
UTF-8 ASCII का सुपरसेट है, लेकिन UTF-16 UCS-2 का सुपरसेट नहीं है। यद्यपि लगभग एक सुपरसेट, यूटीएस -8 में यूसीएस -2 के सही एन्कोडिंग को सीईएसयू -8 के नाम से जाना जाता है; UCS-2 में सरोगेट नहीं है, बस साधारण कोड पॉइंट हैं, इसलिए उन्हें इस तरह अनुवादित किया जाना चाहिए। UTF-16 का वास्तविक लाभ यह है कि UTF-8 के लिए एक पूर्ण पुनर्लेखन की तुलना में UCS-2 कोडबेस को अपग्रेड करना आसान है। मजेदार, हुह?

1
निश्चित रूप से, तकनीकी रूप से UTF-16 UCS-2 का सुपरसेट नहीं है, लेकिन UF-D800 से U + DFFF कभी भी यूटीएफ -16 सरोगेट्स के अलावा किसी भी चीज़ के लिए उपयोग किए गए थे ?
dan04

2
कोई बात नहीं। नेत्रहीन रूप से बाईट्रेस्ट से गुजरने के अलावा किसी भी प्रसंस्करण के लिए आपको सरोगेट जोड़े को डिकोड करने की आवश्यकता होती है, जिसे आप यूसीएस -2 के रूप में मान रहे हैं।

6

UTF-16 हैंडलिंग और स्पेस के बीच सबसे अच्छा समझौता है और इसीलिए अधिकांश प्रमुख प्लेटफॉर्म (Win32, Java, .NET) स्ट्रिंग्स के आंतरिक प्रतिनिधित्व के लिए इसका उपयोग करते हैं।


31
-1 क्योंकि UTF-8 के छोटे या काफी अलग नहीं होने की संभावना है। कुछ निश्चित एशियाई लिपियों के लिए, UTF-8 प्रति ग्लिफ़ प्रति तीन बाइट्स है, जबकि UTF-16 केवल दो हैं, लेकिन यह UTF-8 द्वारा ASCII के लिए केवल एक बाइट होने के कारण संतुलित है (जो अक्सर उत्पाद नामों, आदेशों और इस तरह एशियाई भाषाओं में भी प्रकट होता है) चीजें)। इसके अलावा, उक्त भाषाओं में, एक ग्लिफ़ एक लैटिन चरित्र की तुलना में अधिक जानकारी प्रदान करता है, इसलिए इसके लिए अधिक स्थान लेना उचित है।

32
मैं दोनों विकल्पों के सबसे बुरे पक्षों को एक अच्छा समझौता नहीं कहूंगा।

18
यह UTF-8 से आसान नहीं है। यह चर-लंबाई भी है।
ल्यूसिबल 5

36
UTF-16 के लाभों को एक तरफ छोड़ना: आपने जो उद्धृत किया है वह UTF-16 का उपयोग करते हुए Windows, Java या .NET का कारण नहीं है। विंडोज और जावा एक ऐसे समय में वापस आए जहां यूनिकोड 16-बिट एन्कोडिंग था। UCS-2 तब एक उचित विकल्प था। जब यूनिकोड यूटीएफ -16 में माइग्रेट होने वाला 21-बिट एन्कोडिंग बन गया, तो मौजूदा प्लेटफार्मों में सबसे अच्छा विकल्प था। जिसे संभालने या अंतरिक्ष समझौता करने में आसानी से कोई लेना-देना नहीं था। यह सिर्फ विरासत की बात है।
जॉय

10
.NET यहां विंडोज विरासत को विरासत में मिला है।
जॉय

6

मैंने UTF-16 की बात कभी नहीं समझी है। यदि आप सबसे अधिक स्थान-कुशल प्रतिनिधित्व चाहते हैं, तो UTF-8 का उपयोग करें। यदि आप पाठ को निश्चित लंबाई के रूप में व्यवहार करने में सक्षम होना चाहते हैं, तो UTF-32 का उपयोग करें। यदि आप नहीं चाहते हैं, तो UTF-16 का उपयोग करें। अभी तक बदतर है, क्योंकि यूटीएफ -16 में सभी सामान्य (मूल बहुभाषी विमान) वर्ण एकल कोड बिंदु में फिट होते हैं, कीड़े यह मानते हैं कि यूटीएफ -16 तय की गई लंबाई सूक्ष्म और खोजने में कठिन होगा, जबकि यदि आप करने की कोशिश करते हैं यह UTF-8 के साथ, जैसे ही आप अंतर्राष्ट्रीयकरण करने का प्रयास करते हैं, आपका कोड तेज़ और ज़ोर से विफल हो जाएगा।


6

चूंकि मैं अभी तक टिप्पणी नहीं कर सकता, इसलिए मैं इसे उत्तर के रूप में पोस्ट करता हूं, क्योंकि ऐसा लगता है कि मैं अन्यथा के लेखकों से संपर्क नहीं कर सकता utf8everywhere.org। यह शर्म की बात है कि मुझे स्वतः टिप्पणी विशेषाधिकार प्राप्त नहीं होता है, क्योंकि मेरे पास अन्य स्टैटेक्सचेंज पर पर्याप्त प्रतिष्ठा है।

यह राय के लिए एक टिप्पणी के रूप में अभिप्रेत है : हां, UTF-16 को हानिकारक उत्तर माना जाना चाहिए

एक छोटा सुधार:

char*Windows-API फ़ंक्शंस के ANSI- स्ट्रिंग संस्करणों में UTF-8 को गलती से पास करने से रोकने के लिए , किसी को परिभाषित करना चाहिए UNICODE, नहीं _UNICODE_UNICODEनक्शे कार्य करना पसंद _tcslenकरते हैं wcslen, न कि MessageBoxकरना MessageBoxW। इसके बजाय, UNICODEपरिभाषित बाद की देखभाल करता है। प्रमाण के लिए, यह एमएस विज़ुअल स्टूडियो 2005 के WinUser.hहेडर से है:

#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

बहुत कम से कम, इस त्रुटि को ठीक किया जाना चाहिए utf8everywhere.org

एक सुझाव:

शायद गाइड को डेटा संरचना के वाइड-स्ट्रिंग संस्करण के स्पष्ट उपयोग का एक उदाहरण होना चाहिए, ताकि इसे याद करने / भूलने में कम आसान बनाया जा सके। कार्यों के वाइड-स्ट्रिंग संस्करणों का उपयोग करने के शीर्ष पर डेटा संरचनाओं के वाइड-स्ट्रिंग संस्करणों का उपयोग करने से यह और भी कम संभावना है कि कोई गलती से ऐसे फ़ंक्शन के ANSI- स्ट्रिंग संस्करण को कॉल करता है।

उदाहरण का उदाहरण:

WIN32_FIND_DATAW data; // Note the W at the end.
HANDLE hSearch = FindFirstFileW(widen("*.txt").c_str(), &data);
if (hSearch != INVALID_HANDLE_VALUE)
{
    FindClose(hSearch);
    MessageBoxW(nullptr, data.cFileName, nullptr, MB_OK);
}

माना; धन्यवाद! हम दस्तावेज़ को अपडेट करेंगे। दस्तावेज़ को अभी भी अधिक विकास और डेटाबेस के बारे में जानकारी जोड़ने की आवश्यकता है। हम शब्दों के योगदान को प्राप्त करके खुश हैं।
पावेल रेड्ज़विलोव्स्की

@PavelRadzivilovsky _UNICODEअभी भी है :(
cubuspl42

याद दिलाने के लिए धन्यवाद। क्यूबस, जेले, क्या आप हमारे SVN के लिए एक उपयोगकर्ता चाहेंगे?
पावेल रेड्ज़विलोव्स्की

@ पावेल श्योर, इसकी सराहना करेंगे!
जेल गीत

@JelleGeerts: मैं इस देरी के लिए माफी चाहता हूं। आप हमेशा हमारे ईमेल (घोषणापत्र से जुड़े) या फेसबुक से हमसे संपर्क कर सकते हैं। हमें ढूंढना आसान है। हालांकि मुझे विश्वास है कि हमने आपके द्वारा यहां लाए गए मुद्दे (और मैंने आपको वहां श्रेय दिया था) को तय किया, पूरे यूटीएफ -8 बनाम यूटीएफ -16 बहस अभी भी प्रासंगिक हैं। यदि आपके पास उन निजी चैनलों के माध्यम से हमसे संपर्क करने के लिए स्वतंत्र महसूस करने के लिए अधिक योगदान है।
यबंगलोबिल

5

किसी ने कहा कि UCS4 और UTF-32 समान थे। नहीं, लेकिन मुझे पता है कि आपका क्या मतलब है। उनमें से एक दूसरे का एन्कोडिंग है, हालांकि। काश, वे पहले से धीरज को निर्दिष्ट करने के लिए सोचते, तो हमारे पास यहाँ भी लड़ी जाने वाली अंतहीन लड़ाई नहीं होती। वे देख नहीं सकते थे कि आ रहा है? कम से कम UTF-8 हर जगह समान है (जब तक कि कोई 6-बाइट के साथ मूल कल्पना का पालन नहीं कर रहा है)।

यदि आप UTF-16 का उपयोग करते हैं तो आपको मल्टीबाइट चार्ट के लिए हैंडलिंग को शामिल करना होगा। आप 2N को एक बाइट सरणी में अनुक्रमित करके Nth वर्ण पर नहीं जा सकते। आपको इसे चलना होगा, या चरित्र सूचकांक होंगे। अन्यथा आपने बग लिखा है।

C ++ का वर्तमान ड्राफ्ट अनुमान कहता है कि UTF-32 और UTF-16 में छोटे-एंडियन, बड़े-एंडियन और अनिर्दिष्ट वेरिएंट हो सकते हैं। वास्तव में? यदि यूनिकोड ने यह निर्दिष्ट किया था कि सभी को शुरुआत से ही थोड़ा-सा एंडियन करना होगा तो यह सब सरल हो जाएगा। (मैं बड़े-एंडियन के साथ भी ठीक होता।) इसके बजाय, कुछ लोगों ने इसे एक तरह से लागू किया, कुछ अन्य ने, और अब हम कुछ नहीं के लिए दुःख के साथ फंस गए हैं। कभी-कभी सॉफ्टवेयर इंजीनियर बनना शर्मनाक होता है।


अनिर्दिष्ट अंतःकरण को BOM को पहले वर्ण के रूप में शामिल करना चाहिए, जिसका उपयोग यह निर्धारित करने के लिए किया जाता है कि स्ट्रिंग को किस तरीके से पढ़ा जाना चाहिए। यूसीएस -4 और यूटीएफ -32 वास्तव में आजकल एक ही हैं, यानी 0 और 0x10FFFF के बीच एक संख्यात्मक यूसीएस मान 32 बिट पूर्णांक में संग्रहीत है।

5
@ पुरानी: तकनीकी रूप से, यह सच नहीं है। हालांकि UCS-4 किसी भी 32-बिट पूर्णांक को संग्रहीत कर सकता है, लेकिन UTF-32 को गैर-वर्ण कोड बिंदुओं को संग्रहीत करने से मना किया जाता है जो कि इंटरचेंज के लिए अवैध हैं, जैसे 0xFFFF, 0xFFFE और सभी सरोगेट। UTF ट्रांसपोर्ट एन्कोडिंग है, आंतरिक नहीं।
14

जब तक अलग-अलग प्रोसेसर अलग-अलग बाइट ऑर्डर का उपयोग करना जारी रखते हैं, तब तक एंडियननेस के मुद्दे अपरिहार्य हैं। हालाँकि, यह अच्छा हो सकता है यदि UTF-16 के फ़ाइल भंडारण के लिए "पसंदीदा" बाइट आदेश थे।
क्वर्टी

भले ही UTF-32 कोड बिंदुओं के लिए निश्चित-चौड़ाई है , लेकिन यह वर्णों के लिए निश्चित-चौड़ाई नहीं है । (कुछ "कॉम्बिनेशन कैरेक्टर्स " कहा जाता है?) के बारे में सुना है, तो आप N'th कैरेक्टर में जाकर बस 4N को बाइट ऐरे में इंडेक्स नहीं कर सकते ।
मुसिफिल

2

मुझे नहीं लगता कि अगर डेवलपर पर्याप्त सावधानी बरतता है तो यह हानिकारक है।
और उन्हें इस व्यापार को स्वीकार करना चाहिए अगर वे अच्छी तरह से जानते हैं।

एक जापानी सॉफ्टवेयर डेवलपर के रूप में, मुझे यूसीएस -2 काफी बड़ा लगता है और अंतरिक्ष को सीमित करना स्पष्ट रूप से तर्क को सरल करता है और रनटाइम मेमोरी को कम करता है, इसलिए यूसीएस -2 सीमा के तहत यूटीएफ -16 का उपयोग करना काफी अच्छा है।

फाइलसिस्टम या अन्य अनुप्रयोग हैं जो कोडपॉइंट्स और बाइट्स को आनुपातिक मानते हैं, ताकि कच्चे कोडपॉइंट संख्या को कुछ निश्चित आकार के भंडारण में फिट होने की गारंटी दी जा सके।

एक उदाहरण NTFS और VFAT UCS-2 को उनके फ़ाइल नाम भंडारण एन्कोडिंग के रूप में निर्दिष्ट करता है।

अगर वे उदाहरण वास्तव में UCS-4 का समर्थन करना चाहते हैं, तो मैं वैसे भी सब कुछ के लिए utf-8 का उपयोग करने पर सहमत हो सकता हूं, लेकिन निश्चित लंबाई के कुछ बिंदु हैं:

  1. लंबाई द्वारा आकार की गारंटी दे सकते हैं (डेटा का आकार और कोडपॉइंट की लंबाई आनुपातिक है)
  2. हैश लुकअप के लिए एन्कोडिंग नंबर का उपयोग कर सकते हैं
  3. गैर-संपीड़ित डेटा यथोचित आकार (utf-32 / UCS-4 की तुलना में) है

भविष्य में जब किसी भी एंबेडेड डिवाइस में मेमोरी / प्रोसेसिंग पावर सस्ती होती है, तो हम एक्स्ट्रा कैश मिस या पेज फाल्ट और अतिरिक्त मेमोरी यूसेज के लिए डिवाइस को थोड़ा धीमा होना स्वीकार कर सकते हैं, लेकिन निकट भविष्य में ऐसा नहीं होगा, मुझे लगता है ...


3
इस टिप्पणी को पढ़ने वालों के लिए, यह ध्यान देने योग्य है कि यूसीएस -2 यूटीएफ -16 के समान नहीं है। कृपया समझने के लिए मतभेदों को देखें।
माईकबाकॉक

1

"क्या सबसे लोकप्रिय एनकोडिंग में से एक, यूटीएफ -16 को हानिकारक माना जाना चाहिए?"

संभवतः, लेकिन विकल्प को बहुत बेहतर होने के रूप में नहीं देखा जाना चाहिए।

मूल मुद्दा यह है कि इसके बारे में कई अलग-अलग अवधारणाएं हैं: ग्लिफ़, वर्ण, कोडपॉइंट और बाइट अनुक्रम। इनमें से प्रत्येक के बीच मानचित्रण गैर-तुच्छ है, यहां तक ​​कि एक सामान्यीकरण पुस्तकालय की सहायता से भी। (उदाहरण के लिए, यूरोपीय भाषाओं में कुछ अक्षर जो एक लैटिन-आधारित स्क्रिप्ट के साथ लिखे गए हैं, एक एकल यूनिकोड कोड बिंदु के साथ नहीं लिखे गए हैं। और यह जटिलता के सबसे सरल छोर पर है!) इसका मतलब यह है कि सब कुछ सही होने के लिए काफी आश्चर्यजनक है। मुश्किल; विचित्र कीड़े की उम्मीद की जानी चाहिए (और यहां उनके बारे में केवल विलाप करने के बजाय, संबंधित सॉफ़्टवेयर के अनुरक्षकों को बताएं )।

जिस तरीके से UTF-16 को विरोध के रूप में हानिकारक माना जा सकता है, उसका कहना है, UTF-8 यह है कि BMP के बाहर कोड पॉइंट को अलग करने का एक अलग तरीका है (सरोगेट की एक जोड़ी के रूप में)। अगर कोड बिंदु तक कोड पहुंच या पुनरावृति करना चाहता है, तो इसका मतलब है कि उसे अंतर के बारे में पता होना चाहिए। OTOH, इसका मतलब है कि मौजूदा कोड का एक पर्याप्त निकाय जो "वर्णों" को मानता है, हमेशा दो-बाइट मात्रा में फिट हो सकता है - एक काफी सामान्य, अगर गलत, धारणा - यह सब पुनर्निर्माण के बिना कम से कम काम करना जारी रख सकता है। दूसरे शब्दों में, कम से कम आपको उन पात्रों को देखने को मिलता है जिन्हें सही से संभाला नहीं जा रहा है!

मैं आपके प्रश्न को उसके सिर पर घुमाऊंगा और कहूंगा कि यूनिकोड के पूरे लानत को हानिकारक माना जाना चाहिए और हर किसी को 8-बिट एन्कोडिंग का उपयोग करना चाहिए, सिवाय इसके कि मैंने पिछले 20 वर्षों में देखा है, जहां वह जाता है: भयानक विभिन्न आईएसओ 8859 एनकोडिंग्स पर भ्रम, साथ ही सिरिलिक और EBCDIC सूट के लिए इस्तेमाल होने वाले पूरे सेट, और ... इसके सभी दोषों के लिए यूनिकोड धड़कता है। यदि केवल यह विभिन्न देशों की गलतफहमी के बीच ऐसा एक बुरा समझौता नहीं था।


हमारी किस्मत जानने के बाद, कुछ वर्षों में हम अपने आप को UTF-16 में अंतरिक्ष से बाहर चला पाएंगे। भावहीन।
डोनाल्ड फेलो

3
मूल मुद्दा यह है कि पाठ भ्रामक रूप से कठिन है। उस जानकारी को डिजिटल तरीके से प्रस्तुत करने का कोई तरीका नहीं है। यही कारण है कि तिथियां कठिन हैं, कैलेंडर कठिन हैं, समय कठिन है, व्यक्तिगत नाम कठिन हैं, डाक पते कठिन हैं: जब भी डिजिटल मशीनें मानव सांस्कृतिक निर्माणों के साथ अंतरंग करती हैं, तो जटिलता बढ़ती है। यह जीवन का एक तथ्य है। मनुष्य डिजिटल तर्क पर काम नहीं करता है।
अरस्तू पगलतज़िस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.