UTF-8, UTF-16 और UTF-32 में क्या अंतर हैं?
मैं समझता हूं कि वे सभी यूनिकोड को संग्रहीत करेंगे, और प्रत्येक एक चरित्र का प्रतिनिधित्व करने के लिए अलग-अलग संख्या में बाइट्स का उपयोग करता है। क्या एक को दूसरे के ऊपर चुनने का फायदा है?
UTF-8, UTF-16 और UTF-32 में क्या अंतर हैं?
मैं समझता हूं कि वे सभी यूनिकोड को संग्रहीत करेंगे, और प्रत्येक एक चरित्र का प्रतिनिधित्व करने के लिए अलग-अलग संख्या में बाइट्स का उपयोग करता है। क्या एक को दूसरे के ऊपर चुनने का फायदा है?
जवाबों:
UTF-8 के मामले में एक फायदा है जहां ASCII वर्ण पाठ के एक ब्लॉक में अधिकांश वर्णों का प्रतिनिधित्व करते हैं, क्योंकि UTF-8 इन्हें 8 बिट्स (ASCII की तरह) में एन्कोड करता है। इसमें यह भी लाभप्रद है कि केवल ASCII वर्णों वाली UTF-8 फ़ाइल में ASCII फ़ाइल के समान एन्कोडिंग है।
यूटीएफ -16 बेहतर है जहां एएससीआईआई प्रमुख नहीं है, क्योंकि यह मुख्य रूप से प्रति वर्ण 2 बाइट्स का उपयोग करता है। UTF-8 उच्च क्रम वर्णों के लिए 3 या अधिक बाइट्स का उपयोग करना शुरू कर देगा जहां UTF-16 अधिकांश वर्णों के लिए सिर्फ 2 बाइट्स पर रहता है।
UTF-32 4 बाइट्स में सभी संभावित पात्रों को कवर करेगा। यह यह बहुत फूला हुआ बनाता है। मैं इसका उपयोग करने के लिए किसी भी लाभ के बारे में नहीं सोच सकता।
संक्षेप में:
लंबे समय में: यूटीएफ -8 , यूटीएफ -16 और यूटीएफ -32 देखें ।
wchar_t
बाइट पर osx और linux डिफॉल्ट पर। gcc में एक विकल्प है -fshort-wchar
जो आकार को 2 बाइट्स तक कम करता है, लेकिन std libs के साथ बाइनरी संगतता को तोड़ता है।
UTF-8 चर 1 से 4 बाइट्स है।
UTF-16 चर 2 या 4 बाइट्स है।
UTF-32 4 बाइट तय है ।
नोट: UTF-8 नवीनतम सम्मेलन के साथ 1 से 6 बाइट ले सकता है: https://lists.gnu.org/archive/html/help-flex/2005-01/msg00030.html
यूनिकोड एक विशाल चरित्र सेट को परिभाषित करता है, जो प्रत्येक चित्रमय प्रतीक के लिए एक अद्वितीय पूर्णांक मान निर्दिष्ट करता है (यह एक प्रमुख सरलीकरण है, और वास्तव में सच नहीं है, लेकिन यह इस प्रश्न के उद्देश्यों के लिए पर्याप्त है)। UTF-8/16/32 इसे एनकोड करने के लिए बस अलग-अलग तरीके हैं।
संक्षेप में, UTF-32 प्रत्येक वर्ण के लिए 32-बिट मान का उपयोग करता है। यह उन्हें हर वर्ण के लिए एक निश्चित-चौड़ाई कोड का उपयोग करने की अनुमति देता है।
UTF-16 डिफ़ॉल्ट रूप से 16-बिट का उपयोग करता है, लेकिन यह आपको केवल 65k संभव अक्षर देता है, जो कि पूरे यूनिकोड सेट के लिए पर्याप्त नहीं है। इसलिए कुछ पात्र 16-बिट मानों के जोड़े का उपयोग करते हैं।
और UTF-8 डिफ़ॉल्ट रूप से 8-बिट मानों का उपयोग करता है, जिसका अर्थ है कि 127 पहले मान निश्चित-चौड़ाई वाले सिंगल-बाइट वर्ण हैं (सबसे महत्वपूर्ण बिट का उपयोग यह संकेत देने के लिए किया जाता है कि यह मल्टी-बाइट अनुक्रम की शुरुआत है, 7 छोड़कर वास्तविक चरित्र मूल्य के लिए बिट्स)। अन्य सभी वर्णों को 4 बाइट्स के क्रम के रूप में एन्कोड किया गया है (यदि मेमोरी कार्य करता है)।
और यही हमें फायदे की ओर ले जाता है। कोई भी ASCII-वर्ण सीधे UTF-8 के साथ संगत है, इसलिए विरासत ऐप्स को अपग्रेड करने के लिए, UTF-8 एक सामान्य और स्पष्ट विकल्प है। लगभग सभी मामलों में, यह कम से कम मेमोरी का भी उपयोग करेगा। दूसरी ओर, आप किसी चरित्र की चौड़ाई के बारे में कोई गारंटी नहीं दे सकते। यह 1, 2, 3 या 4 वर्ण चौड़ा हो सकता है, जो स्ट्रिंग हेरफेर को मुश्किल बनाता है।
UTF-32 विपरीत है, यह सबसे अधिक मेमोरी का उपयोग करता है (प्रत्येक वर्ण एक निश्चित 4 बाइट्स चौड़ा है), लेकिन दूसरी ओर, आप जानते हैं कि प्रत्येक वर्ण की यह सटीक लंबाई है, इसलिए स्ट्रिंग हेरफेर बहुत सरल हो जाता है। आप स्ट्रिंग के बाइट्स में लंबाई से केवल एक स्ट्रिंग में वर्णों की संख्या की गणना कर सकते हैं। आप UTF-8 के साथ ऐसा नहीं कर सकते।
UTF-16 एक समझौता है। यह अधिकांश पात्रों को एक निश्चित-चौड़ाई 16-बिट मान में फिट करने देता है । इसलिए जब तक आपके पास चीनी प्रतीक, संगीत नोट या कुछ अन्य नहीं हैं, आप मान सकते हैं कि प्रत्येक वर्ण 16 बिट्स चौड़ा है। यह UTF-32 की तुलना में कम मेमोरी का उपयोग करता है। लेकिन यह कुछ मायनों में "दोनों दुनियाओं में सबसे खराब" है। यह लगभग हमेशा यूटीएफ -8 की तुलना में अधिक मेमोरी का उपयोग करता है, और यह अभी भी उस समस्या से नहीं बचता है जो यूटीएफ -8 (चर-लंबाई) से ग्रस्त है।
अंत में, यह अक्सर मंच के समर्थन के साथ जाने के लिए सहायक होता है। विंडोज यूटीएफ -16 का आंतरिक रूप से उपयोग करता है, इसलिए विंडोज पर, यह स्पष्ट विकल्प है।
लिनक्स थोड़ा भिन्न होता है, लेकिन वे आमतौर पर यूटीएफ -8 का उपयोग उन सभी चीजों के लिए करते हैं जो यूनिकोड-अनुरूप हैं।
इतना छोटा उत्तर: तीनों एनकोडिंग एक ही वर्ण सेट को सांकेतिक शब्दों में बदलना कर सकते हैं, लेकिन वे प्रत्येक चरित्र को अलग-अलग बाइट अनुक्रमों के रूप में दर्शाते हैं।
यूनिकोड एक मानक है और UTF-x के बारे में आप कुछ व्यावहारिक उद्देश्यों के लिए तकनीकी कार्यान्वयन के रूप में सोच सकते हैं:
मैंने अपने ब्लॉगपोस्ट में एक सरल व्याख्या देने की कोशिश की ।
किसी भी वर्ण को एनकोड करने के लिए 32 बिट्स (4 बाइट्स) की आवश्यकता होती है । उदाहरण के लिए, इस योजना का उपयोग करते हुए "A" वर्ण कोड-पॉइंट का प्रतिनिधित्व करने के लिए, आपको 32-बिट बाइनरी संख्या में 65 लिखना होगा:
00000000 00000000 00000000 01000001 (Big Endian)
यदि आप एक करीब से देखते हैं, तो आप ध्यान देंगे कि ASCII योजना का उपयोग करते समय सबसे दाएं सात बिट वास्तव में एक ही बिट्स हैं। लेकिन चूंकि UTF-32 निश्चित चौड़ाई वाली योजना है , इसलिए हमें तीन अतिरिक्त बाइट्स संलग्न करने होंगे। मतलब कि अगर हमारे पास दो फाइलें हैं जिनमें केवल "A" वर्ण है, एक ASCII-एन्कोडेड है और दूसरा UTF-32 एनकोडेड है, उनका आकार 1 बाइट और 4 बाइट्स समान होगा।
बहुत से लोग सोचते हैं कि जैसे यूटीएफ -32 एक कोड-पॉइंट का प्रतिनिधित्व करने के लिए निश्चित चौड़ाई 32 बिट का उपयोग करता है, वैसे ही यूटीएफ -16 की चौड़ाई 16 बिट्स है। गलत!
UTF-16 में कोड बिंदु शायद 16 बिट्स, या 32 बिट्स में दर्शाया गया है। तो यह योजना परिवर्तनशील लंबाई एन्कोडिंग प्रणाली है। UTF-32 पर क्या फायदा है? कम से कम ASCII के लिए, फ़ाइलों का आकार मूल (लेकिन अभी भी दो बार) से 4 गुना अधिक नहीं होगा, इसलिए हम अभी भी ASCII प्रासंगिक नहीं हैं।
चूंकि 7-बिट "ए" चरित्र का प्रतिनिधित्व करने के लिए पर्याप्त हैं, हम अब यूटीएफ -32 की तरह 4 के बजाय 2 बाइट्स का उपयोग कर सकते हैं। ऐसा लगेगा:
00000000 01000001
आपने सही अनुमान लगाया है .. UTF-8 में कोड बिंदु शायद 32, 16, 24 या 8 बिट्स का उपयोग करके दर्शाया गया है, और UTF-16 प्रणाली के रूप में, यह एक चर लंबाई एन्कोडिंग प्रणाली भी है।
अंत में हम "ए" का प्रतिनिधित्व कर सकते हैं उसी तरह हम एएससीआईआई एन्कोडिंग प्रणाली का उपयोग करके इसका प्रतिनिधित्व करते हैं:
01001101
चीनी पत्र "語" पर विचार करें - इसका UTF-8 एन्कोडिंग है:
11101000 10101010 10011110
जबकि इसका UTF-16 एन्कोडिंग छोटा है:
10001010 10011110
प्रतिनिधित्व को समझने के लिए और इसकी व्याख्या कैसे की जाती है, मूल पोस्ट पर जाएं।
जब तक CJK (चीनी, जापानी और कोरियाई) वर्ण स्थान से अधिकांश वर्ण नहीं हो जाते, तब तक UTF-8 सबसे अधिक अंतरिक्ष कुशल होने वाला है।
UTF-32 चरित्र बाइट द्वारा यादृच्छिक पहुँच के लिए सबसे अच्छा है एक बाइट-सरणी में।
0xxxxxxx
का द्विआधारी में रूप है। सभी दो-बाइट वाले पात्रों की शुरुआत 110xxxxx
दूसरे बाइट से होती है 10xxxxxx
। तो मान लीजिए कि दो-बाइट वाले चरित्र का पहला चरित्र खो गया है। जैसे ही आप 10xxxxxx
एक पूर्ववर्ती के बिना देखते हैं 110xxxxxx
, आप यह सुनिश्चित कर सकते हैं कि एक बाइट खो गई थी या दूषित हो गई थी, और उस चरित्र को त्याग दें (या सर्वर या जो भी हो, उससे फिर से अनुरोध करें), और तब तक आगे बढ़ें जब तक आप एक वैध पहला बाइट फिर से न देखें। ।
मैंने MySQL में UTF-8 और UTF-16 के बीच डेटाबेस प्रदर्शन की तुलना करने के लिए कुछ परीक्षण किए।
UTF-32 में सभी पात्रों को 32 बिट्स के साथ कोडित किया गया है। लाभ यह है कि आप आसानी से स्ट्रिंग की लंबाई की गणना कर सकते हैं। नुकसान यह है कि प्रत्येक ASCII वर्ण के लिए आप एक अतिरिक्त तीन बाइट बर्बाद करते हैं।
UTF-8 वर्णों में परिवर्तनशील लंबाई होती है, ASCII वर्णों को एक बाइट (आठ बिट्स) में कोडित किया जाता है, अधिकांश पश्चिमी विशेष वर्णों को या तो दो बाइट्स या तीन बाइट्स में कोडित किया जाता है (उदाहरण के लिए € तीन बाइट्स), और अधिक विदेशी वर्ण ले सकते हैं चार बाइट्स के लिए। स्पष्ट नुकसान यह है, कि एक प्राथमिकता आप स्ट्रिंग की लंबाई की गणना नहीं कर सकते। लेकिन यह UTF-32 की तुलना में लैटिन (अंग्रेजी) वर्णमाला पाठ को कोड करने के लिए बहुत कम बाइट्स लेता है।
UTF-16 भी परिवर्तनशील लंबाई है। वर्णों को दो बाइट्स या चार बाइट्स में कोडित किया जाता है। मैं वास्तव में बात नहीं देख रहा हूँ। इसकी परिवर्तनशील लंबाई होने का नुकसान है, लेकिन इसे UTF-8 के रूप में अधिक स्थान बचाने का लाभ नहीं मिला है।
उन तीनों में से, स्पष्ट रूप से UTF-8 सबसे व्यापक रूप से फैला हुआ है।
आपके विकास के माहौल के आधार पर, आपके पास यह विकल्प भी नहीं हो सकता है कि आपके स्ट्रिंग डेटा प्रकार को आंतरिक रूप से किस प्रकार का उपयोग किया जाए।
लेकिन डेटा संग्रहीत करने और उसका आदान-प्रदान करने के लिए, मैं हमेशा यूटीएफ -8 का उपयोग करूंगा, अगर आपके पास विकल्प है। यदि आपके पास ज्यादातर ASCII डेटा है, तो यह आपको स्थानांतरण करने के लिए सबसे छोटी मात्रा में डेटा देगा, जबकि अभी भी सब कुछ एनकोड करने में सक्षम है। आधुनिक मशीनों पर जाने के लिए कम से कम I / O का अनुकूलन।
जैसा कि उल्लेख किया गया है, अंतर मुख्य रूप से अंतर्निहित चर का आकार है, जो प्रत्येक मामले में अधिक वर्णों का प्रतिनिधित्व करने की अनुमति देने के लिए बड़ा हो जाता है।
हालांकि, फोंट, एन्कोडिंग और चीजें बुरी तरह से (अनावश्यक रूप से जटिल हैं), इसलिए अधिक विस्तार से भरने के लिए एक बड़ी कड़ी की आवश्यकता है:
http://www.cs.tut.fi/~jkorpela/chars.html#ascii
यह सब समझने की उम्मीद मत करो, लेकिन अगर आप बाद में समस्याओं के बारे में नहीं जानना चाहते हैं तो यह जितना संभव हो उतना सीखने लायक है, जितनी जल्दी आप कर सकते हैं (या बस किसी और को आपके लिए इसे सॉर्ट करने के लिए कर सकते हैं)।
पॉल।
संक्षेप में, UTF-16 या UTF-32 का उपयोग करने का एकमात्र कारण क्रमशः गैर-अंग्रेजी और प्राचीन लिपियों का समर्थन करना है।
मैं सोच रहा था कि किसी ने गैर-यूटीएफ -8 एन्कोडिंग को क्यों चुना है जब यह स्पष्ट रूप से वेब / प्रोग्रामिंग उद्देश्यों के लिए अधिक कुशल है।
एक आम गलत धारणा - प्रत्यय संख्या इसकी क्षमता का संकेत नहीं है। वे सभी पूर्ण यूनिकोड का समर्थन करते हैं, बस यूटीएफ -8 एक बाइट के साथ एएससीआईआई को संभाल सकता है, इसलिए सीपीयू और इंटरनेट पर अधिक कुशल / कम भ्रष्ट है।
कुछ अच्छे पढ़ने: http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html और http://utf8everywhere.org