Кіріспе
Бұл мақалада Юникод кодировкалары салыстырылады. Екі жағдай қарастырылады: 8 бит таза орта (мұны болжауға болады) және жоғары биті қойылған байттарды пайдалануға тыйым салатын орта. Бастапқыда мұндай тыйымдар тек жеті дерек битін пайдаланатын сілтемелерге мүмкіндік беру үшін қойылған, бірақ олар кейбір стандарттарда сақталып қалды, сондықтан кейбір стандартқа сәйкес келетін бағдарламалық құралдар осы шектеулерге сәйкес келетін хабарламаларды жасауы керек. Юникод үшін стандарттық сығымдау схемасы және Юникод үшін екілік реттелген сығымдау салыстыру кестелерінен алынып тасталды, себебі олардың мөлшерін анықтау қиын.
This article compares Unicode encodings. Two situations are considered: 8 bit clean environments (which can be assumed), and environments that forbid use of byte values that have the high bit set. Originally such prohibitions were to allow for links that used only seven data bits, but they remain in some standards and so some standard conforming software must generate messages that comply with the restrictions. Standard Compression Scheme for Unicode and Binary Ordered Compression for Unicode are excluded from the comparison tables because it is difficult to simply quantify their size.
Бір-біріне үйлесімділік мәселелері
Тек ASCII символдарын қамтитын UTF-8 файлы ASCII файлымен бірдей. Ескі бағдарламалар, әдетте, UTF-8 кодталған файлдарды, тіпті оларда ASCII емес символдар болса да, өңдей алады. Мысалы, C printf функциясы UTF-8 жолын басып шығара алады, өйткені ол пішімдеу жолын анықтау үшін ASCII '%' символын ғана іздейді және қалған барлық байттарды өзгеріссіз басып шығарады, сондықтан ASCII емес символдар өзгеріссіз шығарылады. UTF-16 және UTF-32 ASCII файлдарымен үйлесімсіз, сондықтан оларды көрсету, басып шығару және өңдеу үшін Unicode-ты түсінетін бағдарламалар қажет, тіпті файлде ASCII жиынтығына жататын символдар ғана бар екені белгілі болса да. Оларда көптеген нөлдік байттар болғандықтан, жолдарды тіпті көшіру сияқты қарапайым операциялар үшін де нөлмен аяқталатын жолдарды стандартты түрде өңдеу арқылы өңдеу мүмкін емес. Сондықтан, тіпті Windows және Java сияқты UTF-16 жүйелерінде UTF-16 мәтіндік файлдары жиі кездеспейді; Unicode қолдауынсыз ASCII немесе ISO 8859-1 сияқты ескі 8 биттік кодтамалар әлі де қолданылады; немесе Unicode үшін UTF-8 қолданылады. Бір сирек кездесетін мысал – macOS (Mac OS X 10.3 Panther және одан кейінгі) қолданбаларында хабарламалардың интернационалданған нұсқаларын іздеу үшін қолданылатын "strings" файлы, ол UTF-16 форматында жұмыс істейді, ал "UTF-8 көмегімен кодталған файлдардың жұмыс істеуі кепілденбеді". XML әдетте UTF-8 ретінде кодталады және барлық XML процессорлары кем дегенде UTF-8 (US ASCII-ді де қамтиды) және UTF-16 қолдауы тиіс.
Тиімділік
UTF-8 кодтауы үшін 8, 16, 24 немесе 32 бит (бірден төрт байтқа дейін) қажет, ал UTF-16 кодтауы үшін 16 немесе 32 бит, ал UTF-32 әрқашан кодтау үшін 32 битті қажет етеді. C0 бақылаулары мен негізгі латын әріптері үшін қолданылатын және олардың ASCII кодтарымен бір-бірге сәйкес келетін алғашқы 128 Юникод кодтық нүктелері (U+0000-ден U+007F-ге дейін) UTF-8-де 8 бит, UTF-16-да 16 бит және UTF-32-де 32 бит көлемінде кодталады. Келесі 1920 әріп (U+0080-ден U+07FF-ге дейін), оның ішінде латын әліпбиінің қалған бөлігі, сондай-ақ грек, кириллица, копт, армян, еврей, араб, сирия, тана және н’ко әріптері UTF-8 және UTF-16-да кодтау үшін 16 бит, ал UTF-32-де 32 бит қажет. U+0800-ден U+FFFF-ге дейін, яғни негізгі көптілді жазықтықтағы (BMP, 0 жазықтығы, U+0000-ден U+FFFF-ге дейін) әріптердің қалған бөлігі, бұл әлемдегі көптеген тірі тілдердің қалған әріптерін қамтиды, UTF-8-ге әріпті кодтау үшін 24 бит, UTF-16-ға 16 бит, ал UTF-32-ге 32 бит қажет. U+010000-ден U+10FFFF-ге дейінгі кодтық нүктелер, қосымша жазықтықтағы әріптерді көрсетеді (1-16 жазықтықтар), UTF-8, UTF-16 және UTF-32 кодтауларында 32 битті қажет етеді. Сондықтан, егер ASCII кодтық нүктелерінің саны U+0800-ден U+FFFF аралығындағы кодтық нүктелерден көп болса, UTF-8 форматындағы файл UTF-16 форматына қарағанда қысқа болады. Күтпеген нәрсе – жоғары диапазонды әріптерді ғана қолданатын тілдерде жазылған нақты құжаттар кеңістіктердің, сандардың, тыныш белгілердің, жаңа жолдардың, HTML белгілерінің және латын әріптерімен жазылған сөздер мен аббревиатуралардың көп қолданылуына байланысты UTF-8 форматында көбінесе қысқа болады. UTF-32 әрқашан U+10000-дан кіші кодтық нүктелер болмаса ұзын болады. UTF EBCDIC-тегі барлық басып шығарылатын әріптер UTF-8-дегідей байттарды пайдаланады, ал көпшілігі C1 бақылау кодтарын бір байт ретінде кодтауға рұқсат беру туралы шешімге байланысты көбірек байтты пайдаланады. Жеті биттік орта үшін UTF-7, цитаталанған басып шығарылатын немесе base64 сияқты басқа Юникод кодтауларымен салыстырғанда, текстің барлық түрлері үшін де кеңістікті тиімдірек пайдаланады (қараңыз: "Жеті биттік орталар").
Өңдеу уақыты
UTF-8 немесе UTF-16 сияқты өзгермелі ұзындығы бар кодтауды қолдану, код бірліктерінің тізбектерімен жұмыс істеуге қарағанда, жеке код бірліктерімен жұмыс істеу қажет болғанда мәтінді өңдеуді қиындатады. Іздеу операциясы таңбалардың өзгермелі өлшемде болуына тәуелді емес, себебі код бірліктерінің тізбегін іздеу бөліністерге назар бөлмейді (бірақ бұл кодтаудың UTF-8 және UTF-16 сияқты өзін-өзі синхрондау қабілетіне ие болуын талап етеді). Көптеген жағдайда, "n-ші таңбаны табу" қажеттігі туындайды және осы үшін белгілі бір ұзындығы бар кодтау қажет деп есептеледі; бірақ, іс жүзінде n саны тек алдыңғы n-1 таңбаны қарастыру арқылы анықталады, сондықтан тізбек бойынша қол жеткізуге қанағаттану керек. Егер бір енділік ретімен сақталған таңбалар тізбегі басқа енділік ретімен жұмыс істейтін құрылғыға жүктелсе, оларды тиімді өңдеу үшін алдымен түрлендіру қажет (немесе екі процессор қолдану керек). UTF-8 сияқты байттық кодтаулар мұндай проблемаға тап болмайды. UTF-16BE және UTF-32BE үлкен енділікпен, ал UTF-16LE және UTF-32LE кіші енділікпен кодтайды.
Өңдеу мәселелері
Өңдеу үшін форматты іздеу, қысқарту және жалпы қауіпсіз өңдеу оңай болуы керек. Барлық қалыпты Юникод кодтамалары код бірлігінің белгілі бір мөлшерін пайдаланады. Форматқа және кодталуға тиіс код нүктесіне байланысты, осы код бірліктерінің бірі немесе бірнешесі Юникод код нүктесін көрсетеді. Оңай іздеу және қысқарту үшін тізбек басқа, ұзақ тізбектің ішінде немесе екі басқа тізбектің шекарасында кездеспеуі тиіс. UTF-8, UTF-16, UTF-32 және UTF-EBCDIC осы маңызды қасиеттерге ие, бірақ UTF-7 және GB 18030 ие емес. Белгілі мөлшердегі таңбалар пайдалы болуы мүмкін, бірақ егер код нүктесіне байт саны белгілі болса да (мысалы, UTF-32-де), біріктірілген таңбалар болғандықтан көрсетілетін әрбір таңбаға байт саны белгілі емес. Осы үйлесімсіздіктерді және әртүрлі кодтау схемаларының басқа да ерекшеліктерін ескере отырып, интерфейстерде бірдей (немесе үйлесімді) протокол арқылы Юникод деректерін өңдеу (мысалы, API/кітапхананы пайдалану, клиент/сервер моделінде Юникод таңбаларын өңдеу және т.б.) жалпы алғанда, процесті жеңілдетіп, қателердің болу мүмкіндігін де жояды. UTF-16 танымал, себебі көптеген API-лар Юникодтың 16 биттік кеңдігі (UCS-2 деп аталады) болған кезден бастап дамыған. Дегенмен, UTF-16-ны пайдалану негізгі көптілді жазықтықтың сыртындағы таңбаларды ерекше жағдайға түсіреді, бұл оларды өңдеуде қате жіберу қаупін арттырады. Сондай-ақ, орнын алмастыратын жұптарды дұрыс өңдемейтін бағдарламаларда тізбектерді біріктіруде де мәселелер болуы мүмкін, сондықтан UTF-32-ні пайдалану көп кодты бірліктерден тұратын таңбаларды нашар өңдеудің жалпы проблемасын шешпейді. Егер сақталған деректердің бірі UTF-8 болса (мысалы, файлдың мазмұны немесе атауы), UTF-16 немесе UTF-32 API ретінде қолданатын жүйені жасау өте қиын. Бұл UTF-8 қолданатын байттық массив физикалық тұрғыда жарамсыз тізбектерді қамтуы мүмкін екендігіне байланысты. Мысалы, UTF-16 API-ді пайдаланып жарамсыз UTF-8 файл атауын түзету мүмкін емес, себебі ешқандай UTF-16 тізбегі сол жарамсыз файл атауына аударылмайды. Керісінше, жарамсыз UTF-16 тізбегін бірегей (бірақ техникалық тұрғыдан жарамсыз) UTF-8 тізбегіне аудару оңай, сондықтан UTF-8 API UTF-8 және UTF-16 файлдары мен атауларын басқара алады, демек, мұндай аралас ортада UTF-8-ге басымдық беріледі. Өкінішке орай, UTF-16 жүйелері көбінесе қолданатын басқа да кең таралған шешім – UTF-8-ді CP 1252 сияқты басқа кодтау ретінде қарастырып, ASCII емес деректердегі можибакені елемеу.
Байланыс пен сақтау үшін
UTF-16 және UTF-32 кодтамаларында енділік анықталмаған, сондықтан оларды байтқа бағдарланған желі арқылы қабылдағанда немесе байтқа бағдарланған жадтан оқығанда байт ретін таңдау қажет. Бұл мәтіннің басында байт реті белгісін пайдалану арқылы немесе үлкен енділік форматын (RFC 2781) қолдану арқылы іске асырылуы мүмкін. UTF-8, UTF-16BE, UTF-32BE, UTF-16LE және UTF-32LE бір байт ретімен стандартталған және оларда мұндай мәселе жоқ. Егер байт ағыны зақымданса, кейбір кодтамалар басқаларына қарағанда жақсырақ қалпына келеді. UTF-8 және UTF EBCDIC осы жағынан ең жақсы, себебі олар келесі код нүктесінің басында зақымдалған немесе жоғалған байттан кейін әрқашан синхрондалуға болады; GB 18030 келесі ASCII емес санға дейін қалпына келтіре алмайды. UTF-16 өзгертілген байттарды қабылдай алады, бірақ жоғалған байттардың тақ санын қабылдамайды, бұл келесі мәтіннің бәрін бұзады (бірақ бұл сирек кездесетін және/немесе тағайындалмаған символдарды тудырады). Егер биттер жоғалса, олардың барлығы келесі мәтінді бұзады, бірақ UTF-8 қайта синхрондалуы мүмкін, өйткені дұрыс емес байт шекаралары бірнеше байттан ұзын мәтінде көбінесе жарамсыз UTF-8 тудырады.
Толықтай
Төмендегі кестелерде әртүрлі Юникод диапазондары үшін кодтық нүктеге шаққандағы байттар саны көрсетілген. Қажетті қосымша түсініктемелер кестеде берілген. Сандар мәтін блогының басындағы және соңындағы қосымша шығындарды ескермейді. Назар аударыңыз: төмендегі кестелерде кодтық нүктеге шаққандағы байттар саны көрсетілген, пайдаланушыға көрінетін "символ" (немесе "графема кластері") бойынша емес. Бір графема кластерін сипаттау үшін бірнеше кодтық нүктелер қажет болуы мүмкін, сондықтан UTF-32 форматында да, жолдарды бөлу немесе біріктіру кезінде сақтық таныту қажет.
Сегіз биттік орта
Кодтар ауқымы (он алтылық) UTF 8 UTF 16 UTF 32 UTF EBCDIC GB 18030 00000000 – 00007F 12411000080 – 00009F GB 2312/GBK-дан мұрагерлік алған таңбалар үшін (мысалы, көптеген қытай таңбалары) 4, ал қалғандары үшін. 0000A0 – 0003FF 2000400 – 0007FF 3000800 – 003FFF 3004000 – 00FFFF 4010000 – 03FFFF 444040000 – 10FFFF 5
Жеті биттік орта
Бұл кестеде барлық ерекше жағдайлар қамтылмаған болуы мүмкін, сондықтан оны тек бағалау және салыстыру үшін пайдалану керек. Кодталған мәтіннің көлемін дәл анықтау үшін тиісті ерекшеліктерді қараңыз. Кодтар диапазоны (он алтылық): UTF-7 UTF-8 quoted printable UTF-8 base64 UTF-16 q.p. UTF-16 base64 GB 18030 q.p. GB 18030 base64 ASCII графикалық таңбалар (U+003D "=" емес) 1 "тікелей таңбалар" үшін (кейбір кодтық нүктелер үшін кодировка параметрлеріне байланысты), 2 U+002B "+" үшін, әйтпесе 000080–00FFFF 1 1/3 4 2/3 1 1/3 0 00003D (теңдік белгісі) 3 6 3 ASCII басқару таңбалары: 000000–00001F және 00007F 1 немесе 3 тікелейлігіне байланысты 1 немесе 3 тікелейлігіне байланысты 000080–0007FF 5 жеке жағдайда, бір байттық таңбалар тізбегінде. Тізбек үшін 2 2/3 әр таңбаға плюс толтыру, оны толық байт санына жеткізу үшін, бастау және аяқтау үшін екі байттан қосып есептегенде 6 2/3 2–6 байт мәндерін қаш тарау қажеттігіне байланысты 4–6 GB2312/GBK-дан мұра етілген таңбалар үшін (мысалы, көптеген қытай таңбалары) 8 қалғандары үшін. 2 2/3 GB2312/GBK-дан мұра етілген таңбалар үшін (мысалы, көптеген қытай таңбалары) 5 1/3 қалғандары үшін. 000800–00FFFF 9 4 0 10000–10FFFF 8 жеке жағдайда, 5 1/3 әр таңбаға плюс толтыру толық санға жеткізу үшін, тізбек үшін 2 байттан қосып есептегенде 12 5 1/3 8–12 орынбасарлардың кіші байттарын қаш тарау қажеттігіне байланысты. 5 1/3 8 5 1/3 Endianness көлемге әсер етпейді (UTF-16BE және UTF-32BE сәйкесінше UTF-16LE және UTF-32LE сияқты көлемде болады). Quoted printable кодировкасында UTF-32-ні пайдалану өте тиімсіз, бірақ егер іске асырылса, кодтық нүктеге 8–12 байт (шамамен 10 байт орташа есеппен) кетеді, атап айтқанда BMP үшін әрбір кодтық нүкте quoted printable/UTF-16-дағы сол кодтан дәл 6 байтқа артық болады. Base64/UTF-32 кез келген кодтық нүктеге 5 1/3 байт кетеді. ASCII басқару таңбасы quoted printable немесе UTF-7 астында тікелей немесе кодталған (эскейптелген) күйде бейнеленуі мүмкін. Нақты басқару таңбасын эскейптеу қажеттілігі көптеген жағдайларға байланысты, бірақ мәтіндік деректердегі жаңа жолдар әдетте тікелей кодталады.
Endianness does not affect sizes (UTF 16BE and UTF 32BE have the same size as UTF 16LE and UTF 32LE, respectively). The use of UTF 32 under quoted printable is highly impractical, but if implemented, will result in 8–12 bytes per code point (about 10 bytes in average), namely for BMP, each code point will occupy exactly 6 bytes more than the same code in quoted printable/UTF 16. Base64/UTF 32 gets 5 1/3 bytes for any code point. An ASCII control character under quoted printable or UTF 7 may be represented either directly or encoded (escaped). The need to escape a given control character depends on many circumstances, but newlines in text data are usually coded directly.
Сығу жүйелері
BOCU 1 және SCSU – Юникод деректерін қысудың екі тәсілі. Олардың кодтауы мәтіннің қаншалықты жиі қолданылуына байланысты. Мәтіннің көп бөлігі бір ғана әріптер жинағын қолданады; мысалы, латын, кириллица, грек және т.б. Бұл қалыпты қолданыс мәтіннің көптеген бөліктерін кодтық таңба бойынша шамамен 1 байтқа дейін қысуға мүмкіндік береді. Бұл күйлі кодтаулар мәтіннің кез келген орнынан кездейсоқ түрде қол жеткізуді қиындатады. Бұл екі қысу схемасы zip немесе bzip2 сияқты басқа қысу схемаларымен салыстырғанда тиімді емес. Балама мақсаттағы қысу схемалары байттардың ұзын тізбектерін бірнеше байтқа дейін қыса алады. SCSU және BOCU 1 қысу схемалары UTF-8, UTF-16 немесе UTF-32 форматында кодталған мәтіннің 25%-дан артық қысылмайды. Басқа балама мақсаттағы қысу жүйелері түпнұсқа мәтіннің көлемін 10%-ға дейін оңай қыса алады. Балама мақсаттағы схемалар жақсы қысу коэффициентіне ие болу үшін күрделі алгоритмдерді және мәтіннің ұзын бөліктерін қажет етеді. Юникод Техникалық Ескертпе #14 қысу схемаларының толық салыстыруын қамтиды.
Тарихи: UTF-5 және UTF-6
Домендік атауларды интернационализациялау үшін UTF 5 және UTF 6 ұсыныстары жасалды. UTF 5 ұсынымы 32-базалық кодтауды қолданды, ал Punycode (басқа нәрселердің арасында, бірақ дәл емес) 36-базалық кодтау болып табылады. 5 биттік код бірлігі үшін UTF 5 атауы 2⁵ = 32 теңдеуімен түсіндіріледі. UTF 6 ұсынысы UTF 5-ке қатарлы ұзындықты кодтауды қосты, мұнда 6 жай ғана UTF 5 плюс 1 дегенді білдіреді. Кейіннен IETF IDN жұмыс тобы осы мақсат үшін тиімді Punycode-ты қабылдады.
Қатаң қудаланбау
UTF-1 ешқашан кеңінен қабылданып, танылмады. UTF-8 әлдеқайда жиі қолданылады. UTF-9 және UTF-18 кодтамалары – 1 сәуір күні жарияланған RFC әзіл-қалжың сипаттамалары, алайда UTF-9 – жұмыс істейтін тоғыздық Unicode түрлендіру форматы, ал UTF-18 – Unicode 12 және одан төмен нұсқаларындағы барлық жеке пайдаланылмаған кодтық нүктелер үшін жұмыс істейтін тоғыздық кодтама, бірақ қосымша жеке пайдалану аймақтарына немесе Unicode 13 және одан кейінгі нұсқаларына қолданылмайды.