क्यों UTF-8 इसकी एन्कोडिंग में कई बिट्स बर्बाद करता है


17

विकिपीडिया लेख के अनुसार , UTF-8 में यह प्रारूप है:

पहला कोड अंतिम कोड बाइट्स बाइट 1 बाइट 2 बाइट 3 बाइट 4
बिंदु बिंदु प्रयुक्त
U + 0000 U + 007F 1 0xxxxxxx
U + 0080 U + 07FF 2 110xxxxx 10xxxxxx
U + 0800 U + FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
U + 10000 U + 1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
x का अर्थ है कि इस बिट का उपयोग कोड बिंदु को चुनने के लिए किया जाता है।

यह प्रत्येक निरंतर बाइट पर दो बिट्स और पहले बाइट में एक बिट बर्बाद करता है। UTF-8 को निम्न की तरह एन्कोड क्यों नहीं किया गया है?

पहला कोड अंतिम कोड बाइट्स बाइट 1 बाइट 2 बाइट 3
बिंदु बिंदु प्रयुक्त
U + 0000 U + 007F 1 0xxxxxxx
U + 0080 U + 3FFF 2 10xxxxxx xxxxxxxx
U + 0800 U + 1FFFFF 3 110xxxxx xxxxxxxx xxxxxxxx

जब कोड बिंदु बेसिक बहुभाषी विमान से बाहर होता है या कोड बिंदु [U + 800, U + 3FFF] होता है तो यह एक बाइट को बचा लेता है।

UTF-8 को अधिक कुशल तरीके से कूटबद्ध क्यों नहीं किया जाता है?


3
cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt आपका प्रस्तावित एन्कोडिंग मूल FSS / UTF प्रस्ताव के समान है। केन थॉम्पसन और रॉब पाइक आत्म-सिंक्रनाइज़िंग संपत्ति चाहते थे।
नवजाल

4
इसके अलावा, आपके एन्कोडिंग को यह गारंटी नहीं लगती है कि ASCII कोड मान गैर-ASCII वर्णों के प्रतिनिधित्व के किसी भी भाग में प्रकट नहीं होते हैं। FSS / UTF और UTF-8 को विरासत कार्यक्रमों के साथ काम करने के लिए डिज़ाइन किया गया है, (उदाहरण के लिए: ASCII NUL और स्लेश (पथ विभाजक) को विभाजक के रूप में उपयोग करने वाले)।
नवजाल

जवाबों:


26

यह इसलिए किया जाता है ताकि आप पता लगा सकें कि आप बहु-बाइट अनुक्रम के बीच में कब हैं। जब यूटीएफ -8 डेटा को देखते हैं 10xxxxxx, तो आप जानते हैं कि यदि आप देखते हैं , कि आप एक मल्टीबाइट चरित्र के बीच में हैं, और जब तक आप 0xxxxxxया तो नहीं देखते हैं, तब तक स्ट्रीम में वापस होना चाहिए 11xxxxxx। अपनी योजना का उपयोग करते हुए, बाइट्स 2 या 3 आसानी से 0xxxxxxxया तो जैसे पेटेंट के साथ समाप्त हो सकता है11xxxxxx

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


लेकिन मेरे साथ स्कीम करें यदि आप किसी चरित्र की भीख मांगने के लिए जाने जाने वाले स्थान पर शुरू करते हैं, तो आप बता सकते हैं कि चरित्र में कितने बाइट हैं और अगले चरित्र की भीख माँगने के लिए हैं।
qbt937 19

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

3
एक अन्य महत्वपूर्ण विशेषता: यदि कोई एम्बेडेड शून्य कोडपॉइंट नहीं है, तो स्ट्रिंग में कोई एम्बेडेड शून्य नहीं हैं।
Deduplicator

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

@ qbt937: अपनी स्कीम का उपयोग करते हुए, यह पता लगाने के लिए कि एक तार में दूसरा क्या है, कैसे पता लगाएगा
सुपरैट

6

आधिकारिक तरीका डिकोडर को यह बताता है कि यह कब टपल के बीच में है और यह बाइट्स को छोड़ना जानता है (या पीछे की ओर जाना) जब तक बाइट शुरू नहीं होती 0या 11; यह कचरा मूल्यों को रोकता है जब एक भी बाइट दूषित हो जाती है।


3

संक्षिप्त उत्तर, आपका प्रस्ताव पहले बाइट और निरंतर बाइट के बीच अंतर नहीं करता है।

पहले बाइट के उच्च अंत में बिट पैटर्न आपको बताता है कि वास्तविक चरित्र का निर्माण कितने बाइट्स के साथ होता है। ये पैटर्न एक स्ट्रिंग को पार्स करते समय कुछ त्रुटि मान्यता भी प्रदान करते हैं। यदि आप एक चरित्र के पहले बाइट (प्रतीत होता है) पढ़ रहे हैं और आपको 10xxxxxx मिलता है, तो आप जानते हैं कि आप एक समय होने वाली घटना से बाहर हैं।


2

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

(2n + 2) बाइट्स के अनुक्रमों पर विचार करें

0xxxxxxx
n times (10xxxxxx, 10xxxxxx)
0xxxxxxx

तथा

n times (10xxxxxx, 10xxxxxx)
(10xxxxxx, 0xxxxxxx)

यदि आपके पास इस अनुक्रम के बाद पहले कोड बिंदु के पहले बाइट के लिए एक संकेतक है, तो आपको यह पता लगाने के लिए सभी बाइट्स की जांच करनी चाहिए कि क्या अंतिम कोडपॉइंट 0xxxxxxx या (10xxxxxx, 0xxxxxxx) है।

वास्तव में अधिक कुशल एन्कोडिंग योजनाएं हैं, जहां पिछले कोड बिंदु पर निरंतर समय में किया जा सकता है, और एक कोड बिंदु के मध्य तक पॉइंटर्स तय किए जा सकते हैं। निम्नलिखित कोडों को अनुमति दें:

X where X < 128
YX where 128 ≤ Y < 236, X < 128
ZYY where 236 ≤ Z < 256, 0 ≤ Y < 236. 

यदि पिछले तीन बाइट्स में से एक of 236 है तो यह एक 3 बाइट अनुक्रम की शुरुआत है, क्योंकि किसी भी वैध 3 बाइट अनुक्रम में दो ऐसे बाइट नहीं हो सकते हैं। अन्यथा, यदि पिछले दो बाइट्स में से एक then 128 है तो यह दो बाइट अनुक्रम की शुरुआत है। अन्यथा, पिछली बाइट एक एकल बाइट <128 है।

एक विकल्प के लिए खोज करना थोड़ा अधिक कठिन हो जाता है। आप शून्य बाइट को बाहर करना चाह सकते हैं ताकि एक स्ट्रिंग में केवल एक शून्य बाइट शामिल हो, यदि इसमें एक शून्य कोड बिंदु हो।


क्या उल्लेख नहीं किया गया है ... - वास्तव में इस प्रकार @ratchet freak के उत्तर में किए गए अवलोकन से सीधे नहीं है।
पियोट्र डोब्रोगोस्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.