UTF-8 और UTF-16 के बीच अंतर?


137

UTF-8 और UTF-16 के बीच अंतर? हमें इनकी आवश्यकता क्यों है?

MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "This is some text";

md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();

जवाबों:


284

मेरा मानना ​​है कि वेब के आसपास इस बारे में बहुत सारे अच्छे लेख हैं, लेकिन यहां एक संक्षिप्त सारांश है।

UTF-8 और UTF-16 दोनों ही चर लंबाई के एनकोडिंग हैं। हालांकि, UTF-8 में एक चरित्र न्यूनतम 8 बिट्स पर कब्जा कर सकता है, जबकि UTF-16 में चरित्र की लंबाई 16 बिट्स के साथ शुरू होती है।

मुख्य UTF-8 पेशेवरों:

  • बुनियादी ASCII वर्ण जैसे अंक, लैटिन वर्ण बिना किसी उच्चारण के, आदि एक बाइट पर कब्जा कर लेते हैं जो US-ASCII प्रतिनिधित्व के समान है। इस तरह से सभी यूएस-एएससीआईआई तार वैध यूटीएफ -8 बन जाते हैं, जो कई मामलों में सभ्य पश्चगामी संगतता प्रदान करता है।
  • कोई अशक्त बाइट्स, जो शून्य-समाप्त स्ट्रिंग्स का उपयोग करने की अनुमति देता है, यह बैकवर्ड संगतता का एक बड़ा सौदा पेश करता है।
  • UTF-8 बाइट ऑर्डर से स्वतंत्र है, इसलिए आपको बिग एंडियन / लिटिल एंडियन मुद्दे के बारे में चिंता करने की ज़रूरत नहीं है।

मुख्य UTF-8 विपक्ष:

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

मुख्य UTF-16 पेशेवरों:

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

मुख्य UTF-16 विपक्ष:

  • US-ASCII स्ट्रिंग्स में बहुत सारे अशक्त बाइट्स, जिसका अर्थ है कोई शून्य-समाप्त स्ट्रिंग्स और बहुत सारी व्यर्थ मेमोरी।
  • कई आम परिदृश्यों में (विशेषकर अमेरिका / यूरोपीय संघ / यूरोपीय संघ के देशों / सिरिलिक वर्णमाला / इज़राइल / अरब देशों / ईरान और कई अन्य लोगों के साथ) "निश्चित रूप से काम करता है" के रूप में इसका इस्तेमाल करते हुए, अक्सर टूटे हुए समर्थन के लिए अग्रणी होता है जहां यह नहीं होता है। इसका मतलब है कि प्रोग्रामर को सरोगेट जोड़े के बारे में पता होना चाहिए और उन मामलों में ठीक से संभालना चाहिए जहां यह मायने रखता है!
  • यह परिवर्तनशील लंबाई है, इसलिए कोडपॉइंट की गिनती या अनुक्रमण करना महंगा है, हालांकि UTF-8 से कम है।

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


3
UTF16 पर केवल BE / LE भाग गुम है :) UTF-8 में एक और नकारात्मक पहलू है, यह UTF16 की तुलना में अधिक समय तक उत्पादन कर सकता है
10:11

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

मैं भी utf-8, कम लंबाई के तत्काल समर्थक का उल्लेख करने के बारे में नहीं सोचा था। Utf-8 के लंबे आउटपुट के बारे में यह एक कारण के लिए 'हो सकता है', फिर भी यदि लक्ष्य पूर्व की ओर है, तो डिफ़ॉल्ट एन्कोडिंग utf-16 होना चाहिए। उदाहरण के लिए md.update (text.getBytes ("UTF-8")); एन्कोडिंग से कोई फर्क नहीं पड़ता क्योंकि हैश दोनों तरीकों से स्थिर है।
bestsss

स्ट्रिंग को बाइट सरणी में बदलने का सबसे तेज़ तरीका कुछ ऐसा है, जिसे नमूने के रूप में पोस्ट किया गया है
bestsss

आप कहते हैं कि वर्णों की UTF-8 में अलग-अलग लंबाई है, इसलिए यह अनुक्रमण और लंबाई की गणना को धीमा कर देता है, लेकिन मुझे शक है कि UTF-16 में उन वर्णों की लंबाई भी अलग-अलग है, क्या अनुक्रमणिका और गणना की लंबाई UTF-16 से अधिक तेज़ होनी चाहिए?
निकी_ज़्स

19

वे यूनिकोड वर्णों का प्रतिनिधित्व करने के लिए बस अलग-अलग योजनाएं हैं।

दोनों चर-लंबाई हैं - UTF-16 मूल बहुभाषी विमान (BMP) में सभी वर्णों के लिए 2 बाइट्स का उपयोग करता है जिसमें अधिकांश वर्ण सामान्य उपयोग में होते हैं।

यूएफएफ -8 बीएमपी में पात्रों के लिए 1 और 3 बाइट्स के बीच का उपयोग करता है, यू + 0000 से यू + 1 एफएफएफएफ की वर्तमान यूनिकोड रेंज में पात्रों के लिए 4 तक, और यू + 7 एफएफएफएफएफ तक एक्स्टेंसिबल है यदि कभी आवश्यक हो जाता है ... लेकिन विशेष रूप से सभी ASCII पात्रों को एक ही बाइट में दर्शाया गया है।

किसी संदेश को पचाने के उद्देश्य से यह मायने नहीं रखेगा कि आप इनमें से किसको चुनते हैं, इसलिए जब तक हर कोई पाचन को फिर से बनाने की कोशिश करता है एक ही विकल्प का उपयोग करता है।

UTF-8 और Unicode के बारे में अधिक जानने के लिए यह पृष्ठ देखें ।

(ध्यान दें कि सभी जावा वर्ण BMP के भीतर UTF-16 कोड बिंदु हैं, U + FFFF से ऊपर के वर्णों का प्रतिनिधित्व करने के लिए आपको जावा में सरोगेट जोड़े का उपयोग करने की आवश्यकता है।)


5

सुरक्षा: केवल UTF-8 का उपयोग करें

UTF-8 और UTF-16 के बीच अंतर? हमें इनकी आवश्यकता क्यों है?

UTF-16 के कार्यान्वयन में कम से कम कुछ सुरक्षा कमजोरियां रही हैं । देखें जानकारी के लिए विकिपीडिया

WHATWG और W3C ने अब घोषित किया है कि वेब पर केवल UTF-8 का उपयोग किया जाना है।

[सुरक्षा] समस्याएँ यहाँ बताई गई हैं, विशेष रूप से UTF-8 का उपयोग करते समय दूर हो जाती हैं, जो कई कारणों में से एक है जो अब सभी चीजों के लिए अनिवार्य एन्कोडिंग है।

अन्य समूह भी यही कह रहे हैं।

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


4

यह UTF-8/16 (सामान्य रूप से असंबंधित है, हालांकि यह UTF16 में परिवर्तित हो जाता है और BE / LE भाग को w / एक लाइन सेट किया जा सकता है), फिर भी नीचे स्ट्रिंग को बाइट में बदलने का सबसे तेज़ तरीका है []। उदाहरण के लिए: प्रदान किए गए मामले (हैश कोड) के लिए अच्छा है। String.getBytes (एन्को) अपेक्षाकृत धीमा है।

static byte[] toBytes(String s){
        byte[] b=new byte[s.length()*2];
        ByteBuffer.wrap(b).asCharBuffer().put(s);
        return b;
    }

-2

UTF-8 और UTF-16 को अलग करने का सरल तरीका उनके बीच की सामान्यताओं की पहचान करना है।

दिए गए चरित्र के लिए एक ही यूनिकोड नंबर साझा करने के अलावा, हर एक का अपना प्रारूप है।

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