2012-05-16 36 views
25

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

यूनिकोड, जीबीके, आदि क्या है? प्रोग्रामिंग भाषा उनका उपयोग कैसे करती है?

क्या मुझे उनके बारे में जानने से परेशान होना चाहिए? क्या प्रोग्रामिंग का एक सरल या तेज़ तरीका है कि मुझे उनके साथ परेशानी न हो?

+6

इसके लिए क्लासिक ऑफ़-साइट संसाधन जोएल स्पॉल्स्की का निबंध है [_ निरपेक्ष न्यूनतम प्रत्येक सॉफ्टवेयर डेवलपर बिल्कुल, यूनिकोड और कैरेक्टर सेट्स (कोई बहाना नहीं है!) के बारे में सकारात्मक रूप से जानना चाहिए (http://www.joelonsoftware.com/ लेख/Unicode.html)। – Raedwald

+1

यह देर से उत्तर दिया गया है, लेकिन मैंने उल्लिखित एन्कोडिंग और वर्णमाला के बारे में कुछ स्पष्टीकरण पोस्ट किए हैं + कुछ शॉर्टकट्स (उदाहरण के लिए जावा के लिए) – bvdb

उत्तर

27

(ध्यान दें कि मैं एक सरल व्याख्या यह है कि अभी भी महत्वपूर्ण बिंदुओं हिट के लिए शिथिल/बोलचाल की भाषा में इनमें से कुछ शर्तों का उपयोग कर रहा हूँ।)

एक बाइट केवल 256 अलग मान हो सकते हैं, 8 बिट जा रहा है।

चूंकि चरित्र सेट में 256 से अधिक वर्णों के साथ चरित्र सेट हैं, इसलिए सामान्य रूप से यह नहीं कह सकता कि प्रत्येक वर्ण एक बाइट है।

इसलिए, मैपिंग्स होनी चाहिए जो बताती हैं कि चरित्र में प्रत्येक चरित्र को बाइट्स के अनुक्रम में कैसे बदलना है। कुछ पात्रों को एक बाइट में मैप किया जा सकता है लेकिन अन्य को एकाधिक बाइट्स में मैप किया जाना होगा।

वे मैपिंग एन्कोडिंग हैं, क्योंकि वे आपको बता रहे हैं कि वर्णों को बाइट्स के अनुक्रमों में कैसे एन्कोड करना है।

यूनिकोड के लिए, बहुत उच्च स्तर पर, यूनिकोड प्रत्येक चरित्र के लिए एक एकल, अद्वितीय संख्या असाइन करने का प्रयास है। स्पष्ट रूप से उस संख्या को बाइट से कुछ बड़ा होना चाहिए क्योंकि 256 से अधिक वर्ण हैं :) जावा यूनिकोड के एक संस्करण का उपयोग करता है जहां प्रत्येक चरित्र को 16-बिट मान असाइन किया जाता है (और यही वजह है कि जावा वर्ण 16 बिट चौड़े हैं और पूर्णांक हैं 0 से 65535 के मान)। जब आप जावा वर्ण का बाइट प्रतिनिधित्व प्राप्त करते हैं, तो आपको उस एन्कोडिंग को JVM को बताना होगा जिसे आप उपयोग करना चाहते हैं ताकि यह पता चल सके कि चरित्र के लिए बाइट अनुक्रम कैसे चुनें।

2

कैरेक्टर एन्कोडिंग वह है जो आप किसी ऐसे व्यक्ति के लिए सॉफ़्टवेयर लिखने की समस्या को हल करने के लिए उपयोग करते हैं जो आपके द्वारा अलग भाषा का उपयोग करता है।

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

आपके पास जो भी भाषा है, उससे बोलने वाली भाषा से तारों का अनुवाद करने का एक तरीका है (अनुवादक कहें)। अब आपको एक ऐसी प्रणाली की आवश्यकता है जो बिना किसी संघर्ष के बाइनरी में दोनों भाषाओं का प्रतिनिधित्व करने में सक्षम है। एन्कोडिंग वह प्रणाली है।

यह आपको सॉफ्टवेयर लिखने की अनुमति देता है जो बाइनरी में भाषाओं का प्रतिनिधित्व करने के तरीके के बावजूद काम करता है।

22

ASCII मौलिक

मूल रूप से 1 चरित्र हमेशा 1 बाइट के रूप में जमा किया गया है। एक बाइट (8 बिट्स) में 256 संभावित मानों को अलग करने की क्षमता है। लेकिन वास्तव में केवल पहले 7 बिट्स का उपयोग किया गया था। तो केवल 128 वर्ण परिभाषित किए गए थे। इस सेट को ASCII वर्ण सेट के रूप में जाना जाता है।

  • 0x00 - 0x1F स्टीयरिंग कोड (जैसे सीआर, वामो, एसटीएक्स, ETX, ईओटी, BEL, शामिल ...)
  • 0x20 - 0x7F शामिल ज्यादातर वर्णमाला वर्ण
  • 0x80 - - 0xFF 8 बिट = अपरिभाषित 0x40 संख्या और विराम चिह्न
  • 0x41 होते हैं।

फ्रेंच, जर्मन और कई अन्य भाषाओं को अतिरिक्त पात्रों की आवश्यकता है। (उदाहरण के लिए à, é, ç, ô, ...) जो ASCII चरित्र सेट में उपलब्ध नहीं थे। इसलिए उन्होंने अपने पात्रों को परिभाषित करने के लिए 8 वें बिट का उपयोग किया। यह "विस्तारित ASCII" के रूप में जाना जाता है।

समस्या यह है कि अतिरिक्त 1 बिट में दुनिया की सभी भाषाओं को कवर करने की पर्याप्त क्षमता नहीं है। इसलिए प्रत्येक क्षेत्र में अपना स्वयं का ASCII संस्करण होता है। कई विस्तारित ASCII एन्कोडिंग (latin-1 बहुत लोकप्रिय हैं)।

लोकप्रिय प्रश्न: "ASCII कोई वर्ण सेट है या यह कोई एन्कोडिंग कि"? ASCII एक चरित्र सेट है। हालांकि, charset और encoding प्रोग्रामिंग में जंगली रूप से समानार्थी के रूप में उपयोग किया जाता है। अगर मैं एन्कोडिंग को संदर्भित करना चाहता हूं जिसमें केवल ASCII वर्ण हैं और कुछ और नहीं है (8 वां बिट हमेशा 0 है): यह US-ASCII है।

यूनिकोड एक कदम आगे चला जाता है

Unicode भी एक वर्ण सेट (नहीं एक एन्कोडिंग) है। यह ASCII मानक जैसे समान वर्णों का उपयोग करता है, लेकिन यह अतिरिक्त वर्णों के साथ सूची को विस्तारित करता है, जो प्रत्येक वर्ण को u+xxxx प्रारूप में कोडपॉइंट देता है। इसमें पूरी दुनिया में उपयोग किए जाने वाले सभी पात्रों (और लोकप्रिय आइकन) को शामिल करने की महत्वाकांक्षा है।

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

GBK एक एन्कोडिंग है, जो यूटीएफ -8 की तरह कई बाइट्स का उपयोग करता है। पहला बाइट ASCII मानक का पालन करता है, इसलिए केवल 7 बिट्स का उपयोग किया जाता है। 8 वीं बिट का उपयोग दूसरी बाइट की उपस्थिति को इंगित करने के लिए किया जाता है, जिसका उपयोग लगभग 22,000 चीनी वर्णों का प्रतिनिधित्व करने के लिए किया जाता है। लेकिन एक महत्वपूर्ण अंतर यह है कि यह यूनिकोड चरित्र सेट का सम्मान नहीं करता है।

माइम प्रकार

माइम प्रकार भी अक्सर एन्कोडिंग समझ लिया जाता है।

फ़ाइल को डीकोड करने का कोई सीधा तरीका नहीं है। यह सभी आदर्श होगा यदि सभी फाइलों में यह इंगित करने के लिए उपसर्ग होता है कि उनके डेटा को एन्कोडिंग किस प्रकार संग्रहीत किया गया था। अंत में यह एन्कोडिंग (उदाहरण के लिए US-ASCII, UTF-8, कुछ सिस्टम डिफ़ॉल्ट निर्धारित करने के लिए एप्लिकेशन (या इसके डेवलपर) पर निर्भर करता है। ..)।

इंटरनेट पर डेटा भेजते समय एक ही समस्या मौजूद है।सौभाग्य से कुछ प्रोटोकॉल जैसे HTTP उपयोग माइम प्रकार घोषणाएं यह निर्दिष्ट करने के लिए कि किस प्रकार का डेटा और डेटासेट डेटा का उपयोग करता है। एक ठेठ HTTP शीर्ष लेख इस में शामिल हैं:

Content-Type: text/html; charset=utf-8 

लेकिन text/xml कि व्यर्थ होगा (क चारसेट पैरामीटर भी नजरअंदाज कर दिया जाएगा)। सामान्य रूप से एक्सएमएल पार्सर फ़ाइल की पहली पंक्ति पढ़ेंगे, <?xml encoding=... टैग की तलाश में। यदि यह वहां है, तो वे उस एन्कोडिंग का उपयोग कर फ़ाइल को फिर से खोल देंगे।

वही समस्या when sending e-mails मौजूद है। एक ई-मेल में एक HTML संदेश या केवल सादा पाठ हो सकता है।

शॉर्टकट

एन्कोडिंग के खतरों के अलावा जावा (और कई अन्य प्रोग्रामिंग भाषाओं) के मामले में, वहाँ भी पात्रों को बाइट्स और पूर्णांकों कास्टिंग क्योंकि उनकी सामग्री विभिन्न श्रेणियों में संग्रहित है की जटिलता है।

  • एक बाइट एक हस्ताक्षरित बाइट (: -128127 लिए रेंज) के रूप में संग्रहीत किया जाता है।
  • एक धारा 255 को सीमा -1 में एक पूर्णांक देता है: - (655350 रेंज)
  • जावा में char टाइप 2 अहस्ताक्षरित बाइट्स में संग्रहित है।

यदि आप जानते हैं कि आपके डेटा में केवल ASCII मान हैं। फिर उचित कौशल के साथ आप बाइट्स से अपने डेटा को वर्णों में पार्स कर सकते हैं या स्ट्रिंग्स में तुरंत लपेट सकते हैं।

// the -1 indicates that there is no data 
int input = stream.read(); 
if (input == -1) throw new EOFException(); 

// bytes must be made positive first. 
byte myByte = (byte) input; 
int unsignedInteger = myByte & 0xFF; 
char ascii = (char)(unsignedInteger); 

जावा में शॉर्टकट पाठकों और लेखकों उपयोग करने के लिए और जब आप उन्हें का दृष्टांत एनकोडिंग निर्दिष्ट करने की है।

// wrap your stream in a reader. 
// specify the encoding 
// The reader will decode the data for you 
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); 

के रूप में एक्सएमएल फाइल यह नहीं बात है कि बहुत है, क्योंकि किसी भी सभ्य डोम या JAXB marshaller कोई एन्कोडिंग विशेषता के लिए जाँच करेगा करता है के लिए पहले समझाया।

+1

बस एक छोटा सा नोट: चूंकि लगभग सभी एन्कोडिंग 128 मूल ASCII वर्णों को उसी तरह से एन्कोड करते हैं, जब तक चूंकि सभी उपयोग किए गए वर्ण इस मूल सेट में परिभाषित किए जाते हैं, आप वास्तव में लगभग किसी भी यादृच्छिक एन्कोडिंग का उपयोग करके अपने संदेश को एन्कोड/डीकोड कर सकते हैं। (उदाहरण के लिए यूटीएफ -8, यूएस-एएससीआईआईआई, लैटिन -1, जीबीके, ...)। – bvdb

+1

भी दिलचस्प है कि बीओएम (बाइट-ऑर्डर-मार्क) जिसका उपयोग एन्कोडिंग के लिए किया जाता है जो एकाधिक बाइट्स (उदा। यूटीएफ -16) का उपयोग करता है। यह इंगित करता है कि बाइट्स में से कौन सा पहला (सबसे महत्वपूर्ण) है। यह मार्कर-बाइट संदेश के सामने रखा गया है। सभ्य 'रीडर' का उपयोग करने का एक और अच्छा कारण। – bvdb

+0

यूनिकोड * की वर्ण तालिका * परिभाषा द्वारा एक एन्कोडिंग है, फिर भी यह i में डबल-एन्कोडेड है। ई। UTF-8। इसलिए यह गलत है, कि यूनिकोड में कोई एन्कोडिंग नहीं है। –

संबंधित मुद्दे