यूटीएफ -16 तय-चौड़ाई या चर-चौड़ाई है? यूटीएफ -8 में बाइट-ऑर्डर की समस्या क्यों नहीं है?


16
  1. यूटीएफ -16 तय-चौड़ाई या चर-चौड़ाई है? मुझे विभिन्न स्रोतों से अलग-अलग परिणाम मिले:

    से http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF :

    यूटीएफ -16 सोलह-बिट विखंडू में यूनिकोड वर्णों को संग्रहीत करता है।

    से http://en.wikipedia.org/wiki/UTF-16/UCS-2 :

    यूटीएफ -16 (16-बिट यूनिकोड ट्रांसफॉर्मेशन फॉर्मेट) यूनिकोड के लिए एक कैरेक्टर एन्कोडिंग है जो कि यूनिकोड कोड स्पेस में 1,112,064 [1] नंबरों (कोड पॉइंट्स) कहा जाता है। यह प्रति कोड बिंदु पर एक या दो 16-बिट कोड इकाइयों की एक चर-लंबाई परिणाम का उत्पादन करता है।

  2. पहले स्रोत से

    UTF-8 का यह भी लाभ है कि एन्कोडिंग की इकाई बाइट है, इसलिए बाइट-ऑर्डर करने के मुद्दे नहीं हैं।

    यूटीएफ -8 में बाइट-ऑर्डर की समस्या क्यों नहीं है? यह चर-चौड़ाई है, और एक चरित्र में एक से अधिक बाइट हो सकती हैं, इसलिए मुझे लगता है कि बाइट-ऑर्डर अभी भी एक समस्या हो सकती है?

धन्यवाद एवं शुभकामनाएँ!


जवाबों:


13

(१) बाइट क्रम का क्या अर्थ है, C में चार का एक अचूक अर्थ? क्या यूटीएफ -16 एक बाइट अनुक्रम है, या फिर यह क्या है? (२) बाइट अनुक्रम का चर लंबाई से कोई लेना-देना क्यों नहीं है?

आप गलत समझ रहे हैं कि एंडियन मुद्दे क्या हैं। यहाँ एक संक्षिप्त सारांश है।

एक 32-बिट पूर्णांक 4 बाइट्स लेता है। अब, हम इन बाइट्स के तार्किक क्रम को जानते हैं। यदि आपके पास 32-बिट पूर्णांक है, तो आप निम्न कोड के साथ इसका उच्च बाइट प्राप्त कर सकते हैं:

uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81

वह सब अच्छा और अच्छा है। जहां समस्या शुरू होती है कि कैसे विभिन्न हार्डवेयर स्टोर और मेमोरी से पूर्णांक प्राप्त करते हैं।

बिग एंडियन क्रम में, एक 4 बाइट का टुकड़ा जिसे आप 32-बिट पूर्णांक के रूप में पढ़ते हैं, पहले बाइट को उच्च बाइट के साथ पढ़ा जाएगा:

[0][1][2][3]

लिटिल एंडियन क्रम में, एक 4 बाइट का टुकड़ा जिसे आप 32-बिट पूर्णांक के रूप में पढ़ते हैं, पहले बाइट को कम बाइट के साथ पढ़ा जाएगा :

[3][2][1][0]

यदि आपके पास एक पॉइंटर को 32-बिट मान के लिए पॉइंटर है, तो आप ऐसा कर सकते हैं:

uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?

C / C ++ के अनुसार, इसका परिणाम अपरिभाषित है। यह 0x81 हो सकता है। या यह 0x32 हो सकता है। तकनीकी रूप से, यह कुछ भी लौटा सकता है, लेकिन वास्तविक प्रणालियों के लिए, यह एक या दूसरे को लौटाएगा।

यदि आपके पास एक मेमोरी एड्रेस का पॉइंटर है, तो आप उस एड्रेस को 32-बिट वैल्यू, 16-बिट वैल्यू या 8-बिट वैल्यू के रूप में पढ़ सकते हैं। एक बड़ी एंडियन मशीन पर, सूचक उच्च बाइट को इंगित करता है; थोड़ा एंडियन मशीन पर, सूचक कम बाइट को इंगित करता है।

ध्यान दें कि यह सब पढ़ने और लिखने के लिए / स्मृति से है। इसका आंतरिक C / C ++ कोड से कोई लेना- देना नहीं है। कोड का पहला संस्करण, वह जो C / C ++ को अपरिभाषित घोषित नहीं करता है, वह हमेशा उच्च बाइट प्राप्त करने के लिए काम करेगा ।

मुद्दा यह है कि जब आप बाइट स्ट्रीम पढ़ना शुरू करते हैं। जैसे कि किसी फाइल से।

16-बिट मानों में 32-बिट वाले समान मुद्दे हैं; उनके पास केवल 4 के बजाय 2 बाइट्स हैं। इसलिए, एक फ़ाइल में 16-बिट मान हो सकते हैं जो बड़े एंडियन या छोटे एंडियन ऑर्डर में संग्रहीत होते हैं।

UTF-16 को 16-बिट मानों के अनुक्रम के रूप में परिभाषित किया गया है । प्रभावी रूप से, यह एक है uint16_t[]। प्रत्येक व्यक्तिगत कोड इकाई एक 16-बिट मान है। इसलिए, UTF-16 को ठीक से लोड करने के लिए, आपको पता होना चाहिए कि डेटा का एंडियन-नेस क्या है।

UTF-8 को 8-बिट मानों के अनुक्रम के रूप में परिभाषित किया गया है । यह एक है uint8_t[]। प्रत्येक व्यक्तिगत कोड इकाई 8-बिट्स आकार में है: एक एकल बाइट।

अब, दोनों UTF-16 और UTF-8 एकाधिक कोड इकाइयों (16-बिट या 8 बिट मान) को एक साथ गठबंधन करने के लिए यूनिकोड कोडपॉइंट (एक "चरित्र" के रूप में है, लेकिन यह है के लिए अनुमति नहीं है कि यह एक सरलीकरण है, सही शब्द )। कोडपॉइंट बनाने वाली इन कोड इकाइयों का क्रम UTF-16 और UTF-8 एनकोडिंग द्वारा निर्धारित किया जाता है।

UTF-16 को संसाधित करते समय, आप एक 16-बिट मान पढ़ते हैं, जो भी एंडियन रूपांतरण की आवश्यकता होती है। फिर, आप पता लगाते हैं कि यह एक सरोगेट जोड़ी है; यदि यह है, तो आप एक और 16-बिट मान पढ़ते हैं, दोनों को मिलाते हैं, और उसी से, आपको यूनिकोड कोडपॉइंट मान मिलता है।

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

इसलिए UTF-8 के साथ कोई एंडियन मुद्दे नहीं हो सकते।


10

जेरेमी बैंक्स का उत्तर जहां तक ​​है, सही है, लेकिन बाइट के आदेश को संबोधित नहीं किया।

जब आप UTF-16 का उपयोग करते हैं, तो अधिकांश ग्लिफ़ दो-बाइट शब्द का उपयोग करके संग्रहीत किए जाते हैं - लेकिन जब शब्द डिस्क फ़ाइल में संग्रहीत होता है, तो आप घटक बाइट्स को संग्रहीत करने के लिए किस क्रम का उपयोग करते हैं?

एक उदाहरण के रूप में, "पानी" शब्द के लिए सीजेके (चीनी) ग्लिफ़ में 6C34 के हेक्साडेसिमल में UTF-16 एन्कोडिंग है। जब आप लिखते हैं कि डिस्क के रूप में दो बाइट्स हैं, तो क्या आप इसे "बिग-एंडियन" (दो बाइट्स 6C 34) के रूप में लिखते हैं? या क्या आप इसे "लिटिल-एंडियन (दो बाइट्स 34 6C हैं) के रूप में लिखते हैं?

UTF-16 के साथ, दोनों ऑर्डर वैध हैं, और आप आमतौर पर इंगित करते हैं कि फ़ाइल में पहला शब्द किसने बनाया है एक बाइट ऑर्डर मार्क (BOM), जो कि बड़े-एंडियन एन्कोडिंग के लिए FE FF है, और छोटे-एंडियन के लिए है एन्कोडिंग FF FE है।

UTF-32 में एक ही समस्या है, और एक ही समाधान है।

UTF-8 में यह समस्या नहीं है, क्योंकि यह परिवर्तनशील लंबाई है, और आप प्रभावी रूप से ग्लिफ़ के बाइट अनुक्रम को लिखते हैं जैसे कि यह थोड़ा-सा एंडियन था। उदाहरण के लिए, अक्षर "P" हमेशा एक बाइट का उपयोग करके एन्कोड किया जाता है - 80 - और प्रतिस्थापन चरित्र हमेशा उस क्रम में दो बाइट्स FF FD का उपयोग करके एन्कोड किया जाता है।

कुछ प्रोग्रामों में एक UTF-8 फ़ाइल की शुरुआत में एक तीन-बाइट इंडिकेटर (EF BB BF) लगाया जाता है, और यह UTF-8 को ASCII जैसी समान एनकोडिंग से अलग करने में मदद करता है, लेकिन MS Windows को छोड़कर यह बहुत आम नहीं है।


धन्यवाद! (1) पत्र "P" UTF-8 में सिर्फ एक बाइट है। प्रतिस्थापन कोड को इसके कोड में क्यों जोड़ा गया है? (2) UTF-8 में, अन्य वर्ण हैं जो UTF-8 में एक से अधिक बाइट हैं। प्रत्येक ऐसे चरित्र के लिए बाइट्स के बीच बाइट-ऑर्डर समस्या क्यों नहीं है?
ऑल जूल

@ समय: (1) आप पी के लिए कोड में प्रतिस्थापन चरित्र नहीं जोड़ते हैं। यदि आप 80 एफएफ एफडी देखते हैं, तो वह दो अक्षर हैं - एक पी वर्ण और एक प्रतिस्थापन चरित्र।
बॉब मर्फी

(2) आप हमेशा उस क्रम में FF FD के रूप में "प्रतिस्थापन चरित्र" के लिए दो बाइट्स लिखते और पढ़ते हैं। केवल एक बाइट-ऑर्डरिंग मुद्दा होगा यदि आप एफडी एफएफ के रूप में "प्रतिस्थापन चरित्र" भी लिख सकते हैं - लेकिन आप नहीं कर सकते हैं; दो बाइट्स का वह क्रम "प्रतिस्थापन चरित्र" के अलावा कुछ और होगा।
बॉब मर्फी

1
@ समय: आप en.wikipedia.org/wiki/UTF-8 के माध्यम से काम करना चाह सकते हैं । यह वास्तव में काफी अच्छा है, और यदि आप इसे और अन्य यूनिकोड से संबंधित विकिपीडिया पृष्ठों को समझ सकते हैं, तो मुझे लगता है कि आप पाएंगे कि आपके पास इसके बारे में अधिक प्रश्न नहीं हैं।
बॉब मर्फी 2

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