Uf-8 के लिए U + xxxxx कोड द्वारा निर्दिष्ट इमोटिकॉन को कन्वर्ट करने के लिए कैसे?


16

इमोटिकॉन्स U + xxxxx के प्रारूप का उपयोग करते हुए निर्दिष्ट किया गया है
जिसमें प्रत्येक x एक हेक्साडेसिमल अंक है।

उदाहरण के लिए, U + 1F615 है आधिकारिक यूनिकोड कंसोर्टियम कोड "उलझन भरा चेहरा" के लिए 😕

जैसा कि मैं अक्सर भ्रमित होता हूं, मेरे पास इस प्रतीक के लिए एक मजबूत आत्मीयता है।

U + 1F615 प्रतिनिधित्व मेरे लिए भ्रामक है, क्योंकि मैंने सोचा था कि केवल यूनिकोड वर्ण के लिए संभव एन्कोडिंग आवश्यक 8, 16, 24 या 32 बिट है, जबकि 5 हेक्स अंक 5x4 = 20 बिट की आवश्यकता है।

मैंने पाया है कि इस प्रतीक को बश में पूरी तरह से अलग हेक्स स्ट्रिंग द्वारा दर्शाया गया है:

$echo -n 😕 | hexdump
0000000 f0 9f 98 95                                    
0000004

$echo -e "\xf0\x9f\x98\x95"
😕

$PS1=$'\xf0\x9f\x98\x95  >'
😕  >

मुझे U + 1F615 की उम्मीद थी कि वह \ x00 \ x01 \ xF6 \ x15 जैसी किसी चीज़ में परिवर्तित होगी ।

मैं इन 2 एनकोडिंग के बीच संबंध नहीं देखता हूं?

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

  • कुछ वेब पेज पर प्रतीक ढूंढना
  • इसे वेब ब्राउज़र के क्लिपबोर्ड पर कॉपी करना
  • वास्तविक कोड की खोज करने के लिए एक हेक्सडम्प के माध्यम से प्रतिध्वनित करने के लिए इसे बैश में चिपकाना।

क्या मैं 32-बिट कोड का निर्धारण करने के लिए इस 20-बिट कोड का उपयोग कर सकता हूं?

क्या इन 2 नंबरों के बीच एक रिश्ता मौजूद है?

जवाबों:


20

UTF-8यूनिकोड की एक चर लंबाई एन्कोडिंग है। इसे ASCII का सुपरसेट बनाया गया है। एन्कोडिंग के विवरण के लिए विकिपीडिया देखें । \x00 \x01 \xF6 \x15होगा UCS-4BEया UTF-32BEएन्कोडिंग।

यूनिकोड कोड पॉइंट से UTF-8 एन्कोडिंग में जाने के लिए, लोकेल का चार्मैप मानकर UTF-8 है (आउटपुट देखें locale charmap), यह सिर्फ है:

$ printf '\U1F615\n'
😕
$ echo -e '\U1F615'
😕
$ confused_face=$'\U1F615'

उत्तरार्द्ध POSIX मानक के अगले संस्करण में होगा

AFAIK, कि वाक्य रचना स्टैंड-अलोन जीएनयू द्वारा 2000 में शुरू की गई थी printfउपयोगिता (के रूप में करने का विरोध किया printfजीएनयू खोल की उपयोगिता), के लिए लाया echo/ printf/ $'...'पहले builtins द्वारा zsh2003 में , 2004 में ksh93, बैश 2010 में (हालांकि ठीक से वहाँ काम नहीं कर रहा 2014 तक ), लेकिन स्पष्ट रूप से अन्य भाषाओं से प्रेरित था।

ksh93के रूप में भी समर्थन करता है printf '\x1f615\n'और printf '\u{1f615}\n'

$'\uXXXX'और $'\UXXXXXXXX'के द्वारा समर्थित हैं zsh, bash, ksh93, mkshऔर FreeBSD sh, जीएनयू printf, जीएनयू echo

कुछ को सभी अंकों की आवश्यकता होती है (जैसा \U0001F615कि विपरीत है \U1F615) हालांकि भविष्य के संस्करणों में बदलने की संभावना है क्योंकि POSIX कम अंकों की अनुमति देगा। किसी भी स्थिति में, यदि \UXXXXXXXXहेक्साडेसिमल अंकों का पालन किया जाना है \U0001F615FOX, जैसा \U1F615FOXकि होता है , तो आपको सभी अंकों की आवश्यकता होती है $'\U001F615F'OX

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

इसलिए, सबसे अच्छी पोर्टेबिलिटी के लिए, सबसे अच्छा यह है कि केवल यूटीएफ -8 स्थानों में इसका उपयोग करें और सभी अंकों का उपयोग करें, और इसमें उपयोग करें $'...':

printf '%s\n' $'\U0001F615'

ध्यान दें कि:

LC_ALL=C.UTF-8; printf '%s\n' $'\U0001F615'

या:

{
  LC_ALL=C.UTF-8
  printf '%s\n' $'\U0001F615'
}

(सहित सभी गोले साथ काम नहीं करेंगे bash), क्योंकि $'\U0001F615'है पार्स से पहले LC_ALLदिया जाता है। (यह भी ध्यान दें कि इस बात की कोई गारंटी नहीं है कि सिस्टम में लोकेल नाम की कोई चीज होगी C.UTF-8)

आपको आवश्यकता होगी:

LC_ALL=C.UTF-8; eval "confused_face=$'\U0001F615'"

या:

LC_ALL=C.UTF-8
printf '%s\n' $'\U0001F615'

(एक कंपाउंड कमांड या फंक्शन के भीतर नहीं)।


रिवर्स के लिए, यूटीएफ -8 एन्कोडिंग से यूनिकोड कोड-पॉइंट तक पहुंचने के लिए, यह अन्य प्रश्न या उस एक को देखें

$ unicode 😕 
U+1F615 CONFUSED FACE
UTF-8: f0 9f 98 95  UTF-16BE: d83dde15  Decimal: 😕
😕
Category: So (Symbol, Other)
Bidi: ON (Other Neutrals)

$ perl -CA -le 'printf "%x\n", ord shift' 😕
1f615

2
ध्यान दें कि यदि \U1F615एक और वैध हेक्साडेसिमल अंक का पालन किया जाता है, तो इसे पलायन अनुक्रम का हिस्सा माना जाएगा। यह काम करने के लिए कि यह उसके बाद क्या है, इसके लिए पर्याप्त अग्रणी शून्य होने के लिए ठीक आठ अंक लंबा होना चाहिए:\U0001F615
kasperd

@kasperd, धन्यवाद। हां, यह ध्यान देने योग्य है। मैंने जवाब में उसे शामिल किया है।
स्टीफन चेज़लस

7

यहां UTF-32 (बड़ा एंडियन) से UTF-8 में बदलने का एक तरीका है

$ confused=$(echo -ne "\x0\x01\xF6\x15" | iconv -f UTF-32BE -t UTF-8)     
$ echo $confused 
😕

आप अपने हेक्स मूल्य 0x01F615को नोटिस करेंगे , 32 बिट्स को भरने के लिए एक अतिरिक्त 0 के साथ गद्देदार।

UTF-8 पर विकिपीडिया पृष्ठ एक यूनिकोड कोड बिंदु से उसके UTF-8 प्रतिनिधित्व को बहुत स्पष्ट रूप से बदल देता है। लेकिन शेल स्क्रिप्टिंग में खुद को करने की कोशिश करना सबसे अच्छा विचार नहीं हो सकता है।

UTF-32 निश्चित-चौड़ाई है, और कोडपॉइंट और UTF-32 प्रतिनिधित्व के बीच पत्राचार तुच्छ है - मान समान है।


6

इसे अपने सिर पर या कागज पर करने का अच्छा तरीका:

  1. यह पता लगाएं कि यह कितने बाइट्स होगा: U + 0080 के तहत मान एक बाइट हैं, अन्यथा U + 0800 के तहत 2 बाइट्स हैं, और U + 10000 के तहत 3 बाइट्स हैं, अन्य 4 बाइट्स। आपके मामले में, 4 बाइट्स।

  2. कन्वर्ट हेक्स टू ऑक्टल 0373025:।

  3. अंत में शुरू करते हुए, अष्टक मानों का एक क्रम प्राप्त करने के लिए एक समय में 2 अष्टक अंकों को छीलें 037 030 025:।

  4. यदि आपके पास बाइट्स की अपेक्षित संख्या से कम अष्टाधारी मूल्य हैं, तो शुरुआत में एक अतिरिक्त 0 जोड़ें 000 037 030 025:।

  5. सभी के लिए लेकिन पहले, 0200पाने के लिए पर जोड़ें 000 0237 0230 0225:।

  6. पहले के लिए, 0300यदि अपेक्षित लंबाई 2 है, 0340अगर यह 3 है, या 0360यदि यह 4 है, तो इसे जोड़ें: पाने के लिए 360 0237 0230 0225

अब अष्टाधारी पलायन की एक स्ट्रिंग के रूप में लिखें: \360\237\230\225। यदि आप चाहें तो वैकल्पिक रूप से वापस हेक्स में परिवर्तित करें।

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