තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.

තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.

ඔබ සංවර්ධකයෙකු නම් සහ කේතීකරණයක් තෝරා ගැනීමේ කාර්යයට ඔබ මුහුණ දෙන්නේ නම්, යුනිකෝඩ් සෑම විටම පාහේ නිවැරදි විසඳුම වනු ඇත. නිශ්චිත නියෝජන ක්‍රමය සන්දර්භය මත රඳා පවතී, නමුත් බොහෝ විට මෙහි විශ්වීය පිළිතුරක් ද ඇත - UTF-8. එහි ඇති හොඳ දෙය නම් එය ඔබට වියදම් නොකර සියලුම යුනිකෝඩ් අක්ෂර භාවිතා කිරීමට ඉඩ සලසයි එසේම බොහෝ අවස්ථාවලදී බයිට් ගොඩක්. ඇත්ත, ලතින් හෝඩියට වඩා වැඩි භාෂා භාවිතා කරන භාෂා සඳහා, "වැඩිය නොවේ" අවම වශයෙන් එක් චරිතයකට බයිට් දෙකක්. ලබා ගත හැකි අක්ෂර 256කට සීමා කරන ප්‍රාග් ඓතිහාසික කේතීකරණ වෙත ආපසු නොයා අපට වඩා හොඳින් කළ හැකිද?

මෙම ප්‍රශ්නයට පිළිතුරු දීමට සහ UTF-8 හි ඇති අතිරික්තය එකතු නොකර ලෝකයේ බොහෝ භාෂාවල රේඛා ගබඩා කිරීමට ඔබට ඉඩ සලසන සාපේක්ෂව සරල ඇල්ගොරිතමයක් ක්‍රියාත්මක කිරීමට මගේ උත්සාහය පිළිබඳව ඔබව හුරු කරවීමට පහත මම යෝජනා කරමි.

වියාචනය. මම වහාම වැදගත් වෙන් කිරීම් කිහිපයක් කරන්නම්: විස්තර කරන ලද විසඳුම UTF-8 සඳහා විශ්වීය ආදේශකයක් ලෙස ඉදිරිපත් නොකෙරේ, එය සුදුසු වන්නේ පටු අවස්ථා ලැයිස්තුවක (පහත ඒවා පිළිබඳ වැඩි විස්තර) පමණක් වන අතර, කිසිම අවස්ථාවක එය තෙවන පාර්ශවීය API (ඒ ගැන නොදන්නා) සමඟ අන්තර් ක්‍රියා කිරීමට භාවිතා නොකළ යුතුය. බොහෝ විට, පොදු කාර්ය සම්පීඩන ඇල්ගොරිතම (උදාහරණයක් ලෙස, deflate) පෙළ දත්ත විශාල පරිමාවක් සංයුක්ත ගබඩා කිරීම සඳහා සුදුසු වේ. ඊට අමතරව, දැනටමත් මගේ විසඳුම නිර්මාණය කිරීමේ ක්‍රියාවලියේදී, මම යුනිකෝඩ් තුළම පවතින ප්‍රමිතියක් සොයා ගත්තෙමි, එය එකම ගැටළුව විසඳයි - එය තරමක් සංකීර්ණ (සහ බොහෝ විට නරක), නමුත් තවමත් එය පිළිගත් ප්‍රමිතියක් වන අතර එය පමණක් නොවේ දණහිස මත එකට. මම ඔහු ගැනත් කියන්නම්.

යුනිකෝඩ් සහ UTF-8 ගැන

ආරම්භ කිරීමට, එය කුමක්ද යන්න ගැන වචන කිහිපයක් යුනිකෝඩ් и UTF-8.

ඔබ දන්නා පරිදි, 8-bit කේතීකරණ ජනප්රිය විය. ඔවුන් සමඟ, සෑම දෙයක්ම සරල විය: අක්ෂර 256 0 සිට 255 දක්වා අංක සමඟ අංකනය කළ හැකි අතර, 0 සිට 255 දක්වා සංඛ්යා පැහැදිලිවම එක් බයිටයක් ලෙස නිරූපණය කළ හැකිය. අපි නැවත ආරම්භයට ගියහොත්, ASCII කේතනය සම්පූර්ණයෙන්ම බිටු 7 කට සීමා වේ, එබැවින් එහි බයිට් නිරූපණයේ වඩාත්ම වැදගත් බිට් එක ශුන්‍ය වන අතර බොහෝ 8-බිට් කේතීකරණ එයට අනුකූල වේ (ඒවා වෙනස් වන්නේ “ඉහළ” තුළ පමණි. කොටස, වඩාත්ම වැදගත් බිට් එක වන ).

යුනිකෝඩ් එම කේතීකරණ වලින් වෙනස් වන්නේ කෙසේද සහ ඒ හා සම්බන්ධ බොහෝ විශේෂිත නිරූපණයන් ඇයි - UTF-8, UTF-16 (BE සහ LE), UTF-32? අපි එය පිළිවෙලට සකස් කරමු.

මූලික යුනිකෝඩ් ප්‍රමිතිය විස්තර කරන්නේ අක්ෂර (සහ සමහර අවස්ථාවලදී, අක්ෂරවල තනි සංරචක) සහ ඒවායේ සංඛ්‍යා අතර ලිපි හුවමාරුව පමණි. තවද මෙම ප්‍රමිතියේ හැකි සංඛ්‍යා රාශියක් ඇත - සිට 0x00 කිරීමට 0x10FFFF (කෑලි 1). එවැනි පරාසයක ඇති සංඛ්‍යාවක් විචල්‍යයකට දැමීමට අවශ්‍ය නම්, අපට බයිට් 114ක් හෝ 112ක් ප්‍රමාණවත් නොවේ. තවද අපගේ ප්‍රොසෙසරය බයිට් තුනක සංඛ්‍යා සමඟ වැඩ කිරීමට සැලසුම් කර නොමැති බැවින්, එක් අක්ෂරයකට බයිට් 1ක් වැනි ප්‍රමාණයක් භාවිතා කිරීමට අපට බල කෙරෙනු ඇත! මෙය UTF-2 වේ, නමුත් එය හරියටම මෙම "නාස්ති" නිසා මෙම ආකෘතිය ජනප්රිය නොවේ.

වාසනාවකට මෙන්, යුනිකෝඩ් තුළ ඇති අක්ෂර අනුපිළිවෙල අහඹු නොවේ. ඔවුන්ගේ සම්පූර්ණ කට්ටලය 17 "ට බෙදා ඇතගුවන් යානා", එක් එක් 65536 අඩංගු වේ (0x10000) "කේත ලකුණු" මෙහි "කේත ලක්ෂ්යය" යන සංකල්පය සරලයි අක්ෂර අංකය, යුනිකෝඩ් මගින් එයට පවරා ඇත. නමුත්, ඉහත සඳහන් කළ පරිදි, යුනිකෝඩ් හි තනි අක්ෂර පමණක් නොව, ඒවායේ සංරචක සහ සේවා ලකුණු ද අංකනය කර ඇත (සමහර විට කිසිවක් අංකයට අනුරූප නොවේ - සමහර විට දැනට, නමුත් අපට මෙය එතරම් වැදගත් නොවේ), එබැවින් සෑම විටම සංකේත ගැන නොව සංඛ්‍යා ගණන ගැන විශේෂයෙන් කතා කිරීම වඩාත් නිවැරදි ය. කෙසේ වෙතත්, පහත දැක්වෙන පරිදි, කෙටිකතාව සඳහා, මම බොහෝ විට "කේත ලක්ෂ්‍යය" යන යෙදුම අඟවමින් "සංකේතය" යන වචනය භාවිතා කරමි.

තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.
යුනිකෝඩ් ගුවන් යානා. ඔබට පෙනෙන පරිදි, එයින් බොහොමයක් (ගුවන් යානා 4 සිට 13 දක්වා) තවමත් භාවිතයට නොගනී.

වඩාත්ම කැපී පෙනෙන දෙය නම් සියලුම ප්‍රධාන “පල්ප්” ශුන්‍ය තලයේ පිහිටා තිබීමයි, එය හැඳින්වෙන්නේ "මූලික බහුභාෂා තලය". පේළියක නවීන භාෂාවකින් (චීන ඇතුළුව) පෙළ අඩංගු නම්, ඔබ මෙම ගුවන් යානයෙන් ඔබ්බට නොයනු ඇත. නමුත් ඔබට ඉතිරි යුනිකෝඩ් කපා දැමිය නොහැක - උදාහරණයක් ලෙස, ඉමොජි ප්‍රධාන වශයෙන් අවසානයේ පිහිටා ඇත ඊළඟ ගුවන් යානය"පරිපූරක බහුභාෂා තලය"(එය දක්වා විහිදේ 0x10000 කිරීමට 0x1FFFF) එබැවින් UTF-16 මෙය සිදු කරයි: සියලුම අක්ෂර ඇතුළත් වේ මූලික බහුභාෂා තලය, අනුරූප බයිට් දෙකක අංකයක් සමඟ "පවතින පරිදි" කේතනය කර ඇත. කෙසේ වෙතත්, මෙම පරාසයේ ඇති සමහර සංඛ්‍යා නිශ්චිත අක්ෂර නොපෙන්වයි, නමුත් මෙම බයිට් යුගලයෙන් පසුව අප තවත් එකක් සලකා බැලිය යුතු බව පෙන්නුම් කරයි - මෙම බයිට් හතරේ අගයන් එකට එකතු කිරීමෙන්, අපට ආවරණය වන අංකයක් ලැබේ. සම්පූර්ණ වලංගු යුනිකෝඩ් පරාසය. මෙම අදහස "ආදේශක ජෝඩු" ලෙස හැඳින්වේ - ඔබ ඔවුන් ගැන අසා ඇති.

එබැවින් UTF-16 සඳහා "කේත ලක්ෂ්‍යයකට" දෙකක් හෝ (ඉතා දුර්ලභ අවස්ථාවන්හිදී) බයිට් හතරක් අවශ්‍ය වේ. මෙය නිතරම බයිට් හතරක් භාවිතා කරනවාට වඩා හොඳයි, නමුත් ලතින් (සහ අනෙකුත් ASCII අක්ෂර) මේ ආකාරයෙන් කේතනය කළ විට ශුන්‍ය මත ඉඩ අඩක් අපතේ යයි. UTF-8 මෙය නිවැරදි කිරීම සඳහා නිර්මාණය කර ඇත: එහි ASCII පෙර පරිදිම එක් බයිටයක් පමණක් භාවිතා කරයි; සිට කේත 0x80 කිරීමට 0x7FF - බයිට් දෙකක්; සිට 0x800 කිරීමට 0xFFFF - තුන, සහ සිට 0x10000 කිරීමට 0x10FFFF - සිව්. එක් අතකින්, ලතින් හෝඩිය හොඳ වී ඇත: ASCII සමඟ ගැළපුම නැවත පැමිණ ඇති අතර, බෙදා හැරීම වඩා ඒකාකාරව බයිට් 1 සිට 4 දක්වා "පැතිරී" ඇත. නමුත් ලතින් හැර වෙනත් හෝඩියේ, අහෝ, UTF-16 හා සසඳන විට කිසිදු ආකාරයකින් ප්‍රතිලාභයක් නොලැබෙන අතර, බොහෝ දෙනෙකුට දැන් දෙකක් වෙනුවට බයිට් තුනක් අවශ්‍ය වේ - බයිට් දෙකක වාර්තාවකින් ආවරණය වන පරාසය 32 ගුණයකින් අඩු වී ඇත. 0xFFFF කිරීමට 0x7FF, සහ චීන හෝ, උදාහරණයක් ලෙස, ජෝර්ජියානු කිසිවක් එයට ඇතුළත් නොවේ. සිරිලික් සහ තවත් අක්ෂර පහක් - හුරේ - වාසනාවන්ත, එක් චරිතයකට බයිට් 2ක්.

මෙය සිදු වන්නේ ඇයි? UTF-8 අක්ෂර කේත නියෝජනය කරන්නේ කෙසේදැයි බලමු:
තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.
ඉලක්කම් නිරූපනය කිරීම සඳහා, සංකේතය සමඟ ලකුණු කර ඇති බිටු මෙහි භාවිතා වේ x. බයිට් දෙකක වාර්තාවක එවැනි බිටු 11 ක් පමණක් ඇති බව දැකිය හැකිය (16 න්). මෙහි ඇති ප්‍රමුඛ බිටු වලට ඇත්තේ සහායක කාර්යයක් පමණි. බයිට් හතරක වාර්තාවක දී, කේත ලක්ෂ්‍ය අංකය සඳහා බිට් 21 න් 32 ක් වෙන් කරනු ලැබේ - බයිට් තුනක් (මුළු බිටු 24 ක් ලබා දෙන) ප්‍රමාණවත් බව පෙනේ, නමුත් සේවා සලකුණු අධික ලෙස අනුභව කරයි.

මේක නරකද? ඇත්තෙන්ම නැහැ. එක් අතකින්, අප අභ්‍යවකාශය ගැන බොහෝ සැලකිල්ලක් දක්වන්නේ නම්, අප සතුව සම්පීඩන ඇල්ගොරිතම ඇති අතර එමඟින් සියලුම අමතර එන්ට්‍රොපි සහ අතිරික්තය පහසුවෙන් ඉවත් කළ හැකිය. අනෙක් අතට, යුනිකෝඩ් හි අරමුණ වූයේ හැකි උපරිම විශ්වීය කේතීකරණය සැපයීමයි. උදාහරණයක් ලෙස, අපට UTF-8 හි කේතනය කරන ලද රේඛාවක් කලින් ASCII සමඟ පමණක් ක්‍රියා කළ කේතයට භාර දිය හැකි අතර, එය ASCII පරාසයෙන් ඇත්ත වශයෙන්ම නොමැති අක්ෂරයක් දකිනු ඇතැයි බිය නොවන්න (සියල්ලට පසු, UTF-8 හි සියල්ල බිට් බිට් වලින් ආරම්භ වන බයිට් - මෙය හරියටම ASCII වේ). ආරම්භයේ සිටම විකේතනය නොකර විශාල නූලකින් කුඩා වලිගයක් කපා හැරීමට අපට අවශ්‍ය නම් (හෝ හානියට පත් කොටසකින් පසු තොරතුරු කොටසක් ප්‍රතිස්ථාපනය කරන්න), චරිතයක් ආරම්භ වන ඕෆ්සෙට් එක සොයා ගැනීම අපට පහසුය (එය ප්‍රමාණවත් වේ. බිට් උපසර්ගයක් ඇති බයිට් මඟ හැරීමට 10).

ඇයි එහෙනම් අලුත් දෙයක් නිර්මාණය කරන්නේ?

ඒ අතරම, විටින් විට deflate වැනි සම්පීඩන ඇල්ගොරිතම දුර්වල ලෙස අදාළ වන අවස්ථා තිබේ, නමුත් ඔබට නූල්වල සංයුක්ත ගබඩාවක් ලබා ගැනීමට අවශ්‍ය වේ. පුද්ගලිකව, මම ගොඩනැගීම ගැන සිතන විට මෙම ගැටලුවට මුහුණ දුන්නා සම්පීඩිත උපසර්ග ගස අත්තනෝමතික භාෂාවල වචන ඇතුළු විශාල ශබ්දකෝෂයක් සඳහා. එක් අතකින්, සෑම වචනයක්ම ඉතා කෙටි වේ, එබැවින් එය සම්පීඩනය කිරීම අකාර්යක්ෂම වනු ඇත. අනෙක් අතට, මා සලකා බැලූ ගස ක්‍රියාත්මක කිරීම සැලසුම් කර ඇත්තේ ගබඩා කර ඇති තන්තුවේ සෑම බයිටයක්ම වෙනම ගස් ශීර්ෂයක් ජනනය වන පරිදි ය, එබැවින් ඒවායේ සංඛ්‍යාව අවම කිරීම ඉතා ප්‍රයෝජනවත් විය. මගේ පුස්තකාලයේ Az.js (හි ඇති පරිදි pymorphy2, එය පදනම් වූ) සමාන ගැටළුවක් සරලව විසඳිය හැකිය - නූල් ඇසුරුම් කර ඇත DAWG-ශබ්දකෝෂය, එහි ගබඩා කර ඇත හොඳ පැරණි CP1251. නමුත්, තේරුම් ගැනීමට පහසු වන පරිදි, මෙය හොඳින් ක්‍රියාත්මක වන්නේ සීමිත හෝඩියකට පමණි - එවැනි ශබ්දකෝෂයකට චීන භාෂාවෙන් රේඛාවක් එක් කළ නොහැක.

වෙනමම, එවැනි දත්ත ව්‍යුහයක් තුළ UTF-8 භාවිතා කරන විට පැන නගින තවත් එක් අප්‍රසන්න සූක්ෂ්මතාවයක් සටහන් කිරීමට මම කැමැත්තෙමි. ඉහත පින්තූරයේ දැක්වෙන්නේ අක්ෂරයක් බයිට් දෙකක් ලෙස ලියා ඇති විට එහි අංකයට අදාළ බිටු පේළියකට නොපැමිණෙන අතර එය බිටු යුගලයකින් වෙන් කරන බවයි. 10 අතරමැද දී: 110xxxxx 10xxxxxx. මේ නිසා, දෙවන බයිටයේ පහළ බිටු 6 අක්ෂර කේතයෙන් පිටාර ගැලීමේදී (එනම්, සංක්‍රාන්තියක් සිදු වේ. 1011111110000000), එවිට පළමු බයිටය ද වෙනස් වේ. "p" අක්ෂරය බයිට් වලින් දක්වා ඇති බව පෙනේ 0xD0 0xBF, සහ ඊළඟ "r" දැනටමත් ඇත 0xD1 0x80. උපසර්ග ගසක, මෙය මාපිය නෝඩය දෙකට බෙදීමට තුඩු දෙයි - උපසර්ගය සඳහා එකක් 0xD0, සහ තවත් එකක් සඳහා 0xD1 (සම්පූර්ණ සිරිලික් හෝඩිය දෙවන බයිටයෙන් පමණක් සංකේතනය කළ හැකි වුවද).

මට මොනවද ලැබුණේ

මෙම ගැටලුවට මුහුණ දුන් මම බිටු සමඟ ක්‍රීඩා කිරීමට පුරුදු වීමට තීරණය කළ අතර, ඒ සමඟම සමස්තයක් ලෙස යුනිකෝඩ් ව්‍යුහය ගැන ටිකක් හොඳින් දැන හඳුනා ගන්න. එහි ප්‍රතිඵලය වූයේ UTF-C කේතීකරණ ආකෘතියයි ("C" for සංගත), එය කේත ලක්ෂ්‍යයකට බයිට් 3කට වඩා වැය නොකරන අතර බොහෝ විට ඔබට වියදම් කිරීමට පමණක් ඉඩ සලසයි සම්පූර්ණ කේතන රේඛාව සඳහා එක් අමතර බයිට් එකක්. මෙය බොහෝ ASCII නොවන හෝඩියේ එවැනි කේතීකරණයක් බවට පත්වේ. UTF-30 ට වඩා 60-8% වඩා සංයුක්ත වේ.

මම ආකෘති පත්රයේ කේතනය සහ විකේතනය කිරීමේ ඇල්ගොරිතම ක්රියාත්මක කිරීම පිළිබඳ උදාහරණ ඉදිරිපත් කර ඇත JavaScript සහ Go පුස්තකාල, ඔබට ඒවා ඔබේ කේතය තුළ නිදහසේ භාවිත කළ හැක. නමුත් එක් අර්ථයකින් මෙම ආකෘතිය “බයිසිකලයක්” ලෙස පවතින බව මම තවමත් අවධාරණය කරමි, එය භාවිතා කිරීම මම නිර්දේශ නොකරමි. ඔබට එය අවශ්‍ය වන්නේ මන්දැයි නොදැන. මෙය තවමත් බරපතල "UTF-8 වැඩිදියුණු කිරීම" වඩා අත්හදා බැලීමකි. එසේ වුවද, එහි ඇති කේතය මනාව, සංක්ෂිප්තව, විශාල අදහස් සහ පරීක්ෂණ ආවරණයක් සහිතව ලියා ඇත.

තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.
පරීක්ෂණ ප්රතිඵල සහ UTF-8 සමඟ සැසඳීම

මමත් කළා demo පිටුව, ඔබට ඇල්ගොරිතමයේ කාර්ය සාධනය ඇගයීමට ලක් කළ හැකි අතර, පසුව එහි මූලධර්ම සහ සංවර්ධන ක්රියාවලිය ගැන මම ඔබට තවත් කියන්නම්.

අතිරික්ත බිටු ඉවත් කිරීම

මම UTF-8 පදනමක් ලෙස ගත්තා, ඇත්ත වශයෙන්ම. එහි වෙනස් කළ හැකි පළමු සහ වඩාත්ම පැහැදිලිව පෙනෙන දෙය නම් එක් එක් බයිටයේ සේවා බිට් ගණන අඩු කිරීමයි. උදාහරණයක් ලෙස, UTF-8 හි පළමු බයිටය සෑම විටම ආරම්භ වේ 0, හෝ සමඟ 11 - උපසර්ගයක් 10 එය ඇත්තේ පහත බයිට් වල පමණි. උපසර්ගය ආදේශ කරමු 11 මත 1, සහ ඊළඟ බයිට් සඳහා අපි උපසර්ග සම්පූර්ණයෙන්ම ඉවත් කරන්නෙමු. කුමක් සිදුවේවිද?

0xxxxxxx - බයිට් 1
10xxxxxx xxxxxxxx - බයිට් 2 ක්
110xxxxx xxxxxxxx xxxxxxxx - බයිට් 3 ක්

ඉන්න, බයිට් හතරේ වාර්තාව කොහෙද? නමුත් එය තවදුරටත් අවශ්‍ය නොවේ - බයිට් තුනකින් ලියන විට, දැන් අපට බිට් 21ක් ඇති අතර මෙය දක්වා ඇති සියලුම සංඛ්‍යා සඳහා ප්‍රමාණවත් වේ. 0x10FFFF.

අපි මෙහි පූජා කළේ කුමක්ද? වැදගත්ම දෙය වන්නේ බෆරයේ අත්තනෝමතික ස්ථානයක සිට අක්ෂර මායිම් හඳුනා ගැනීමයි. අපට හිතුවක්කාර බයිටයක් පෙන්වා එයින් ඊළඟ චරිතයේ ආරම්භය සොයාගත නොහැක. මෙය අපගේ ආකෘතියේ සීමාවකි, නමුත් ප්රායෝගිකව මෙය කලාතුරකින් අවශ්ය වේ. අපට සාමාන්‍යයෙන් මුල සිටම බෆරය හරහා ධාවනය කිරීමට හැකි වේ (විශේෂයෙන් කෙටි රේඛා සම්බන්ධයෙන්).

බයිට් 2 කින් භාෂා ආවරණය කිරීමේ තත්වය ද යහපත් වී ඇත: දැන් බයිට් දෙකේ ආකෘතිය බිට් 14 ක පරාසයක් ලබා දෙන අතර මේවා දක්වා කේත වේ 0x3FFF. චීන ජාතිකයන් අවාසනාවන්තයි (ඔවුන්ගේ චරිත බොහෝ දුරට පරාසයක පවතී 0x4E00 කිරීමට 0x9FFF), නමුත් ජෝර්ජියානුවන් සහ තවත් බොහෝ ජනයා වඩාත් විනෝදජනකයි - ඔවුන්ගේ භාෂා ද එක් චරිතයකට බයිට් 2 කට ගැලපේ.

කේතීකරණ තත්ත්වය ඇතුළු කරන්න

දැන් අපි රේඛාවල ගුණාංග ගැන සිතමු. ශබ්ද කෝෂයේ බොහෝ විට එකම හෝඩියේ අක්ෂර වලින් ලියා ඇති වචන අඩංගු වන අතර වෙනත් බොහෝ පාඨ සඳහාද මෙය සත්‍ය වේ. මෙම හෝඩිය එක් වරක් සඳහන් කර එහි ඇති අකුරේ අංකය පමණක් සඳහන් කිරීම හොඳය. යුනිකෝඩ් වගුවේ අක්ෂර සැකසීම අපට උපකාරී වේදැයි බලමු.

ඉහත සඳහන් කළ පරිදි, යුනිකෝඩ් බෙදා ඇත ගුවන් යානය කේත 65536 බැගින්. නමුත් මෙය ඉතා ප්රයෝජනවත් බෙදීමක් නොවේ (දැනටමත් පවසා ඇති පරිදි, බොහෝ විට අපි ශුන්ය තලයේ සිටිමු). විසින් බෙදීම වඩාත් සිත්ගන්නා කරුණකි කුට්ටි. මෙම පරාසයන්ට තවදුරටත් ස්ථාවර දිගක් නොමැති අතර වඩාත් අර්ථාන්විත වේ - රීතියක් ලෙස, සෑම එකක්ම එකම හෝඩියේ අක්ෂර ඒකාබද්ධ කරයි.

තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.
බෙංගාලි හෝඩියේ අක්ෂර අඩංගු කොටසකි. අවාසනාවකට, ඓතිහාසික හේතූන් මත, මෙය ඉතා ඝන නොවන ඇසුරුම් සඳහා උදාහරණයකි - අක්ෂර 96 ක් බ්ලොක් කේත ලක්ෂ්‍ය 128 ක් පුරා අවුල් සහගත ලෙස විසිරී ඇත.

කුට්ටි වල ආරම්භය සහ ඒවායේ ප්‍රමාණය සෑම විටම 16 ගුණාකාර වේ - මෙය පහසුව සඳහා සරලව සිදු කෙරේ. මීට අමතරව, බොහෝ වාරණ 128 හෝ 256 ගුණාකාර අගයන් මත ආරම්භ වී අවසන් වේ - උදාහරණයක් ලෙස, මූලික සිරිලික් හෝඩිය බයිට් 256 ක් ගනී. 0x0400 කිරීමට 0x04FF. මෙය බෙහෙවින් පහසු ය: අපි උපසර්ගය එක් වරක් සුරැකුවහොත් 0x04, එවිට ඕනෑම සිරිලික් අක්ෂරයක් එක් බයිටයකින් ලිවිය හැකිය. ඇත්ත, මේ ආකාරයෙන් අපට ASCII වෙත (සහ පොදුවේ වෙනත් ඕනෑම අක්ෂරයකට) නැවත පැමිණීමේ අවස්ථාව අහිමි වනු ඇත. එබැවින් අපි මෙය කරන්නෙමු:

  1. බයිට් දෙකක් 10yyyyyy yxxxxxxx අංකයක් සහිත සංකේතයක් පමණක් නොවේ yyyyyy yxxxxxxx, නමුත් වෙනස් කරන්න වත්මන් හෝඩිය මත yyyyyy y0000000 (එනම් අඩුම වැදගත් ඒවා හැර අනෙකුත් සියලුම බිටු අපට මතකයි බිට් 7 යි);
  2. එක බයිට් එකක් 0xxxxxxx වත්මන් හෝඩියේ ස්වභාවය මෙයයි. එය 1 පියවරේදී අප මතක තබා ගත් ඕෆ්සෙට් එකට එකතු කළ යුතුය. අපි හෝඩිය වෙනස් නොකළ අතර, ඕෆ්සෙට් එක බිංදුවයි, එබැවින් අපි ASCII සමඟ ගැළපුම පවත්වා ගත්තෙමු.

එලෙසම බයිට් 3ක් අවශ්‍ය කේත සඳහා:

  1. බයිට් තුනක් 110yyyyy yxxxxxxx xxxxxxxx අංකයක් සහිත සංකේතයක් දක්වන්න yyyyyy yxxxxxxx xxxxxxxx, වෙනස් කරන්න වත්මන් හෝඩිය මත yyyyyy y0000000 00000000 (බාල අය හැර අනෙක් සියල්ල මතකයි බිට් 15 යි), සහ අපි දැන් සිටින කොටුව සලකුණු කරන්න දිගු මාදිලිය (හෝඩිය නැවත ද්විත්ව බයිට් එකකට වෙනස් කරන විට, අපි මෙම ධජය නැවත සකසන්නෙමු);
  2. බයිට් දෙකක් 0xxxxxxx xxxxxxxx දිගු මාදිලියේ එය වත්මන් හෝඩියේ චරිතයයි. ඒ හා සමානව, අපි එය පියවර 1 සිට ඕෆ්සෙට් සමඟ එකතු කරමු. එකම වෙනස වන්නේ දැන් අපි බයිට් දෙකක් කියවන බවයි (අපි මෙම මාදිලියට මාරු වූ නිසා).

හොඳයි වගේ: දැන් අපට එම 7-බිට් යුනිකෝඩ් පරාසයෙන් අක්ෂර කේතනය කිරීමට අවශ්‍ය වන අතර, අපි ආරම්භයේදී අමතර බයිට් 1 ක් සහ එක් අක්ෂරයකට එක් බයිටයක් වැය කරමු.

තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.
පෙර අනුවාද වලින් එකකින් වැඩ කිරීම. එය දැනටමත් බොහෝ විට UTF-8 පරාජය කරයි, නමුත් වැඩිදියුණු කිරීමට තවමත් ඉඩ තිබේ.

නරක කුමක්ද? පළමුව, අපට කොන්දේසියක් ඇත, එනම් වත්මන් හෝඩියේ ඕෆ්සෙට් සහ පිරික්සුම් කොටුව දිගු මාදිලිය. මෙය තවදුරටත් අපව සීමා කරයි: දැන් එකම අක්ෂර විවිධ සන්දර්භවලදී වෙනස් ලෙස කේතනය කළ හැක. උදාහරණයක් ලෙස, උපසිරසි සෙවීම, මෙය සැලකිල්ලට ගනිමින් සිදු කළ යුතු අතර, බයිට් සංසන්දනය කිරීමෙන් පමණක් නොවේ. දෙවනුව, අපි හෝඩිය වෙනස් කළ විගසම, ASCII අක්ෂර කේතනය කිරීමත් සමඟ එය නරක විය (මෙය ලතින් හෝඩිය පමණක් නොව, හිස්තැන් ඇතුළු මූලික විරාම ලකුණු ද වේ) - ඔවුන්ට හෝඩිය නැවත 0 ට වෙනස් කිරීමට අවශ්‍ය වේ, එනම්, නැවතත් අමතර බයිට් එකක් (ඉන්පසු අපගේ ප්‍රධාන කරුණ වෙත ආපසු යාමට තවත් එකක්).

එක අකුරක් හොඳයි, දෙකක් හොඳයි

ඉහත විස්තර කර ඇති තුනට තවත් එකක් මිරිකා, අපගේ බිට් උපසර්ග ටිකක් වෙනස් කිරීමට උත්සාහ කරමු:

0xxxxxxx - සාමාන්‍ය මාදිලියේ බයිට් 1, දිගු මාදිලියේ 2
11xxxxxx - බයිට් 1
100xxxxx xxxxxxxx - බයිට් 2 ක්
101xxxxx xxxxxxxx xxxxxxxx - බයිට් 3 ක්

තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.

දැන් බයිට් දෙකක වාර්තාවක අඩුවෙන් ලබාගත හැකි බිට් එකක් ඇත - කේත ලකුණු දක්වා 0x1FFFසහ නැත 0x3FFF. කෙසේ වෙතත්, එය තවමත් ද්විත්ව බයිට් UTF-8 කේත වලට වඩා සැලකිය යුතු ලෙස විශාල වේ, බොහෝ පොදු භාෂා තවමත් ගැලපේ, වඩාත්ම කැපී පෙනෙන අලාභය පහත වැටී ඇත hiragana и කටකනා, ජපනුන් දුකෙන්.

මොකක්ද මේ අලුත් code එක? 11xxxxxx? මෙය ප්‍රමාණයෙන් අක්ෂර 64 කින් යුත් කුඩා “සැපයුමක්” වේ, එය අපගේ ප්‍රධාන හෝඩියට අනුපූරක වේ, එබැවින් මම එය සහායක ලෙස හැඳින්වුවෙමි (සහායක) හෝඩිය. අපි වත්මන් හෝඩිය මාරු කරන විට, පැරණි හෝඩියේ කෑල්ලක් සහායක බවට පත්වේ. උදාහරණයක් ලෙස, අපි ASCII සිට Cyrillic වෙත මාරු කළෙමු - ගබඩාවේ දැන් අක්ෂර 64 ක් අඩංගු වේ ලතින් හෝඩිය, අංක, අවකාශය සහ කොමාව (ASCII නොවන පාඨවල නිතර ඇතුළත් කිරීම්). ASCII වෙත ආපසු මාරු වන්න - සහ සිරිලික් හෝඩියේ ප්‍රධාන කොටස සහායක හෝඩිය බවට පත්වේ.

හෝඩිය දෙකකට ප්‍රවේශ වීමට ස්තූතිවන්ත වන්නට, අපට හෝඩිය මාරු කිරීම සඳහා අවම පිරිවැයක් සහිත පෙළ විශාල ප්‍රමාණයක් හැසිරවිය හැකිය (විරාම ලකුණු බොහෝ විට ASCII වෙත ආපසු යාමට හේතු වේ, නමුත් ඉන් පසුව අපට අමතර හෝඩියෙන් ASCII නොවන අක්ෂර රාශියක් ලැබෙනු ඇත. නැවත මාරු කිරීම ).

ප්‍රසාද දීමනාව: උප හෝඩිය උපසර්ග කිරීම 11xxxxxx සහ එහි ආරම්භක ඕෆ්සෙට් තෝරා ගැනීම 0xC0, අපි CP1252 සමඟ අර්ධ ගැළපුම ලබා ගනිමු. වෙනත් වචන වලින් කිවහොත්, CP1252 හි කේතනය කර ඇති බොහෝ (නමුත් සියල්ලම නොවේ) බටහිර යුරෝපීය පාඨ UTF-C හි සමාන වනු ඇත.

කෙසේ වෙතත්, මෙහිදී දුෂ්කරතාවයක් පැන නගී: ප්රධාන හෝඩියෙන් සහායක එකක් ලබා ගන්නේ කෙසේද? ඔබට එකම ඕෆ්සෙට් එකක් තැබිය හැකිය, නමුත් - අහෝ - මෙහි යුනිකෝඩ් ව්‍යුහය දැනටමත් අපට එරෙහිව ක්‍රීඩා කරයි. බොහෝ විට හෝඩියේ ප්‍රධාන කොටස බ්ලොක් එකේ ආරම්භයේ නොමැත (උදාහරණයක් ලෙස, රුසියානු අගනුවර "A" හි කේතය ඇත 0x0410, සිරිලික් බ්ලොක් ආරම්භ වුවද 0x0400) මේ අනුව, පළමු අක්ෂර 64 ස්ටෑෂ් තුළට ගත් පසු, අපට හෝඩියේ වලිගය වෙත ප්‍රවේශය අහිමි විය හැකිය.

මෙම ගැටළුව විසඳීම සඳහා, මම විවිධ භාෂාවලට අනුරූප වන බ්ලොක් කිහිපයක් හස්තීයව ගිය අතර, ඒවා සඳහා ප්‍රධාන එක තුළ සහායක හෝඩියේ ඕෆ්සෙට් නියම කළෙමි. ලතින් හෝඩිය, ව්යතිරේකයක් ලෙස, සාමාන්යයෙන් base64 ලෙස නැවත සකස් කරන ලදී.

තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.

අවසාන ස්පර්ශයන්

අපි අවසාන වශයෙන් සිතමු අපට යමක් වැඩිදියුණු කළ හැක්කේ කොතැනින්ද කියා.

ආකෘතිය බව සලකන්න 101xxxxx xxxxxxxx xxxxxxxx දක්වා අංක කේතනය කිරීමට ඔබට ඉඩ සලසයි 0x1FFFFF, සහ යුනිකෝඩ් කලින් අවසන් වේ, at 0x10FFFF. වෙනත් වචන වලින් කිවහොත්, අවසාන කේත ලක්ෂ්‍යය ලෙස නිරූපණය කෙරේ 10110000 11111111 11111111. එමනිසා, පළමු බයිට් ආකෘතියේ නම් අපට පැවසිය හැකිය 1011xxxx (කොහෙද xxxx 0 ට වඩා වැඩි), එවිට එය වෙනත් දෙයක් අදහස් කරයි. උදාහරණයක් ලෙස, ඔබට එක් බයිටයකින් කේතනය කිරීම සඳහා නිරන්තරයෙන් ලබා ගත හැකි තවත් අක්ෂර 15 ක් එකතු කළ හැකිය, නමුත් මම එය වෙනස් ආකාරයකින් කිරීමට තීරණය කළෙමි.

අපි බලමු දැන් බයිට් තුනක් අවශ්‍ය යුනිකෝඩ් බ්ලොක් ගැන. මූලික වශයෙන්, දැනටමත් සඳහන් කර ඇති පරිදි, මේවා චීන අක්ෂර වේ - නමුත් ඒවා සමඟ කිසිවක් කිරීමට අපහසුය, ඒවායින් 21 දහසක් ඇත. නමුත් හිරගනා සහ කටකනා ද එහි පියාසර කළහ - තවද ඒවායින් බොහොමයක් නොමැත, දෙසියයකට වඩා අඩුය. තවද, අපට ජපන් ජාතිකයින් මතක ඇති බැවින්, ඉමෝජි ද ඇත (ඇත්ත වශයෙන්ම, ඒවා යුනිකෝඩ් හි බොහෝ ස්ථානවල විසිරී ඇත, නමුත් ප්‍රධාන කොටස් පරාසයේ ඇත 0x1F300 - 0x1FBFF) කේත ලක්ෂ්‍ය කිහිපයකින් එකවර එකලස් කරන ලද ඉමෝජි දැන් ඇති බව ඔබ සිතන්නේ නම් (උදාහරණයක් ලෙස, ඉමොජිතවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය. කේත 7 කින් සමන්විත වේ!), එවිට එක් එක් බයිට් තුනක් වැය කිරීම සම්පූර්ණ ලැජ්ජාවකි (එක් නිරූපකයක් සඳහා බයිට් 7×3 = 21, නපුරු සිහිනයක්).

එබැවින්, අපි emoji, hiragana සහ katakana වලට අනුරූප තෝරාගත් පරාස කිහිපයක් තෝරා, ඒවා එක් අඛණ්ඩ ලැයිස්තුවකට නැවත අංකනය කර ඒවා තුනක් වෙනුවට බයිට් දෙකක් ලෙස කේතනය කරමු:

1011xxxx xxxxxxxx

නියමයි: ඉහත සඳහන් කළ ඉමොජිතවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය., කේත ලක්ෂ්‍ය 7 කින් සමන්විත වන අතර, UTF-8 හි බයිට් 25 ක් ගන්නා අතර, අපි එයට ගැලපෙන්නෙමු 14 (එක් එක් කේත ලක්ෂ්‍යය සඳහා හරියටම බයිට් දෙකක්). මාර්ගය වන විට, හබ්ර් එය ජීර්ණය කිරීම ප්‍රතික්ෂේප කළේය (පැරණි සහ නව සංස්කාරකයේ), එබැවින් මට එය පින්තූරයක් සමඟ ඇතුළත් කිරීමට සිදු විය.

අපි තවත් එක් ගැටළුවක් විසඳීමට උත්සාහ කරමු. අපට මතක ඇති පරිදි, මූලික හෝඩිය අත්යවශ්ය වේ ඉහළ බිටු 6 යි, අපි මතක තබාගෙන ඊළඟ විකේතනය කළ එක් එක් සංකේතයේ කේතයට ඇලවීම. බ්ලොක් එකේ ඇති චීන අක්ෂර සම්බන්ධයෙන් 0x4E00 - 0x9FFF, මෙය බිට් 0 හෝ 1 වේ. මෙය ඉතා පහසු නොවේ: මෙම අගයන් දෙක අතර (එනම් බයිට් තුනක් වැය කරන්න) අපට නිරන්තරයෙන් හෝඩිය මාරු කිරීමට අවශ්‍ය වනු ඇත. නමුත් දිගු මාදිලියේදී, කෙටි මාදිලිය භාවිතයෙන් අපි කේතනය කරන අක්ෂර ගණන අඩු කළ හැකි බව සලකන්න (ඉහත විස්තර කර ඇති සියලුම උපක්‍රම වලින් පසුව, මෙය 10240) - එවිට හයිරොග්ලිෆ් පරාසය මාරු වනු ඇත. 0x2600 - 0x77FF, සහ මෙම අවස්ථාවෙහිදී, මෙම සම්පූර්ණ පරාසය පුරාවටම, වඩාත්ම වැදගත් බිටු 6 (21න්) 0 ට සමාන වනු ඇත. මේ අනුව, හයිරොග්ලිෆ් අනුපිළිවෙලවල් එක් හයිරොග්ලිෆ් එකකට බයිට් දෙකක් භාවිතා කරයි (එතරම් විශාල පරාසයක් සඳහා ප්‍රශස්ත වේ), නොමැතිව අකාරාදී ස්විචයන් ඇති කරයි.

විකල්ප විසඳුම්: SCSU, BOCU-1

යුනිකෝඩ් ප්‍රවීණයන්, ලිපියේ මාතෘකාව කියවීමෙන් පසු, යුනිකෝඩ් ප්‍රමිතීන් අතර කෙලින්ම ඇති බව ඔබට මතක් කිරීමට බොහෝ විට ඉක්මන් වනු ඇත. යුනිකෝඩ් සඳහා සම්මත සම්පීඩන ක්‍රමය (SCSU), එය ලිපියේ විස්තර කර ඇති ආකාරයට සමාන කේතන ක්‍රමයක් විස්තර කරයි.

මම අවංකවම පිළිගනිමි: මම එහි පැවැත්ම ගැන ඉගෙන ගත්තේ මගේ තීරණය ලිවීමේ ගැඹුරින් ගිලී ගිය පසුවය. මම ඒ ගැන මුල සිටම දැන සිටියා නම්, මගේම ප්‍රවේශයක් ඉදිරිපත් කිරීම වෙනුවට ක්‍රියාත්මක කිරීමක් ලිවීමට මම බොහෝ විට උත්සාහ කරමි.

සිත්ගන්නා කරුණ නම්, SCSU මා විසින්ම ඉදිරිපත් කළ අදහස්වලට බොහෝ සමාන අදහස් භාවිතා කිරීමයි (“අක්ෂර” සංකල්පය වෙනුවට ඔවුන් “කවුළු” භාවිතා කරයි, සහ මට වඩා ඒවා ලබා ගත හැකිය). ඒ අතරම, මෙම ආකෘතියට අවාසි ද ඇත: එය කේතනය කිරීමට වඩා සම්පීඩන ඇල්ගොරිතම වලට ටිකක් සමීප වේ. විශේෂයෙන්, ප්‍රමිතිය බොහෝ නිරූපණ ක්‍රම ලබා දෙයි, නමුත් ප්‍රශස්ත එකක් තෝරා ගන්නේ කෙසේදැයි නොකියයි - මේ සඳහා, කේතකය යම් ආකාරයක හූරිස්ටික් භාවිතා කළ යුතුය. මේ අනුව, හොඳ ඇසුරුම් නිෂ්පාදනය කරන SCSU කේතකයක් මගේ ඇල්ගොරිතමයට වඩා සංකීර්ණ සහ අපහසු වනු ඇත.

සංසන්දනය කිරීම සඳහා, මම SCSU හි සාපේක්ෂව සරල ක්‍රියාත්මක කිරීමක් JavaScript වෙත මාරු කළෙමි - කේත පරිමාව අනුව එය මගේ UTF-C හා සැසඳිය හැකි බව පෙනී ගියේය, නමුත් සමහර අවස්ථාවල ප්‍රති result ලය සියයට දහයකින් නරක විය (සමහර විට එය එය ඉක්මවා යා හැක, නමුත් බොහෝ නොවේ). උදාහරණයක් ලෙස, හෙබ්‍රෙව් සහ ග්‍රීක භාෂාවෙන් පාඨ UTF-C මගින් සංකේතනය කර ඇත SCSU වලට වඩා 60% හොඳයි (සමහරවිට ඒවායේ සංයුක්ත අක්ෂර මාලාව නිසා විය හැක).

වෙනමම, මම SCSU වලට අමතරව යුනිකෝඩ් සංයුක්තව නියෝජනය කිරීමට තවත් ක්‍රමයක් ඇති බව එකතු කරමි - BOCU-1, නමුත් එය MIME ගැළපුම සඳහා ඉලක්ක කරයි (මට අවශ්‍ය නොවීය) සහ කේතනය කිරීමට තරමක් වෙනස් ප්‍රවේශයක් ගනී. මම එහි කාර්යක්ෂමතාවය තක්සේරු කර නැත, නමුත් එය SCSU ට වඩා වැඩි විය නොහැකි බව මට පෙනේ.

හැකි වැඩිදියුණු කිරීම්

මා ඉදිරිපත් කළ ඇල්ගොරිතම සැලසුම අනුව විශ්වීය නොවේ (මගේ ඉලක්ක යුනිකෝඩ් කොන්සෝටියම් හි ඉලක්ක වලින් බොහෝ දුරට අපසරනය වන්නේ මෙයයි). එය මූලික වශයෙන් එක් කාර්යයක් සඳහා (උපසර්ග ගසක බහුභාෂා ශබ්ද කෝෂයක් ගබඩා කිරීම) සඳහා සංවර්ධනය කර ඇති බව මම දැනටමත් සඳහන් කර ඇති අතර එහි සමහර විශේෂාංග වෙනත් කාර්යයන් සඳහා නොගැලපේ. නමුත් එය ප්‍රමිතියක් නොවීම ප්ලස් එකක් විය හැක - ඔබට එය ඔබගේ අවශ්‍යතාවයට ගැලපෙන පරිදි පහසුවෙන් වෙනස් කළ හැක.

උදාහරණයක් ලෙස, පැහැදිලි ආකාරයෙන් ඔබට රාජ්‍යයේ පැවැත්මෙන් මිදිය හැකිය, අස්ථායී කේතීකරණය කරන්න - විචල්‍යයන් යාවත්කාලීන නොකරන්න offs, auxOffs и is21Bit කේතකය සහ විකේතකය තුළ. මෙම අවස්ථාවේදී, එකම හෝඩියේ අක්ෂර අනුපිළිවෙල ඵලදායී ලෙස ඇසුරුම් කිරීමට නොහැකි වනු ඇත, නමුත් සන්දර්භය නොතකා එකම අක්ෂරය සෑම විටම එකම බයිට් වලින් කේතනය කර ඇති බවට සහතිකයක් ඇත.

ඊට අමතරව, ඔබට පෙරනිමි තත්ත්වය වෙනස් කිරීමෙන් විශේෂිත භාෂාවකට කේතකය සකස් කළ හැකිය - උදාහරණයක් ලෙස, රුසියානු පාඨ කෙරෙහි අවධානය යොමු කිරීම, ආරම්භයේදීම කේතකය සහ විකේතකය සකසන්න. offs = 0x0400 и auxOffs = 0. රාජ්ය රහිත මාදිලිය සම්බන්ධයෙන් මෙය විශේෂයෙන් අර්ථවත් කරයි. සාමාන්‍යයෙන්, මෙය පැරණි බිට් අට කේතනය භාවිතා කිරීමට සමාන වනු ඇත, නමුත් අවශ්‍ය පරිදි සියලුම යුනිකෝඩ් වලින් අක්ෂර ඇතුළු කිරීමේ හැකියාව ඉවත් නොකර.

කලින් සඳහන් කළ තවත් අඩුපාඩුවක් නම්, UTF-C හි කේතනය කර ඇති විශාල පෙළෙහි අත්තනෝමතික බයිටයකට ආසන්නතම අක්ෂර මායිම සොයා ගැනීමට ඉක්මන් ක්‍රමයක් නොමැති වීමයි. ඔබ කේතනය කරන ලද බෆරයෙන් බයිට් 100 ක් කපා හැරියහොත්, ඔබට කිසිවක් කළ නොහැකි කුණු ලබා ගැනීමේ අවදානමක් ඇත. කේතනය බහු-ගිගාබයිට් ලඝු-සටහන් ගබඩා කිරීම සඳහා නිර්මාණය කර නැත, නමුත් සාමාන්යයෙන් මෙය නිවැරදි කළ හැක. බයිට් 0xBF කිසි විටෙකත් පළමු බයිටය ලෙස නොපෙන්විය යුතුය (නමුත් දෙවන හෝ තුන්වන විය හැක). එබැවින්, කේතනය කිරීමේදී, ඔබට අනුපිළිවෙල ඇතුළත් කළ හැකිය 0xBF 0xBF 0xBF සෑම එකක්ම, කියන්න, 10 KB - එවිට, ඔබට මායිමක් සොයා ගැනීමට අවශ්‍ය නම්, සමාන සලකුණක් සොයා ගන්නා තෙක් තෝරාගත් කැබැල්ල පරිලෝකනය කිරීමට එය ප්‍රමාණවත් වේ. අන්තිම අනුගමනය කරමින් 0xBF චරිතයක ආරම්භය බව සහතිකයි. (විකේතනය කිරීමේදී, බයිට් තුනක මෙම අනුපිළිවෙල නොසලකා හැරිය යුතුය.)

සාරාංශ කිරීමට

ඔබ මෙතෙක් කියවා ඇත්නම්, සුබ පැතුම්! යුනිකෝඩ් ව්‍යුහය ගැන ඔබ මා මෙන්ම අලුත් දෙයක් (හෝ ඔබේ මතකය අලුත් කර) ඉගෙන ගනු ඇතැයි මම බලාපොරොත්තු වෙමි.

තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.
ආදර්ශන පිටුව. හෙබ්‍රෙව් උදාහරණය UTF-8 සහ SCSU යන දෙකටම වඩා වාසි පෙන්වයි.

ඉහත විස්තර කර ඇති පර්යේෂණ ප්‍රමිතීන් උල්ලංඝනය කිරීමක් ලෙස නොසැලකිය යුතුය. කෙසේ වෙතත්, මම සාමාන්යයෙන් මගේ කාර්යයේ ප්රතිඵල ගැන සෑහීමකට පත්වෙමි, එබැවින් මම ඔවුන් සමඟ සතුටු වෙමි කොටස: උදාහරණයක් ලෙස, කුඩා JS පුස්තකාලයක බර වන්නේ බයිට් 1710ක් පමණි (සහ ඇත්ත වශයෙන්ම පරායත්තතා නොමැත). මා ඉහත සඳහන් කළ පරිදි, ඇයගේ කාර්යය සොයාගත හැකිය demo පිටුව (UTF-8 සහ SCSU සමඟ සැසඳිය හැකි පාඨ මාලාවක් ද ඇත).

අවසාන වශයෙන්, මම නැවත වරක් UTF-C භාවිතා කරන අවස්ථා වෙත අවධානය යොමු කරමි වටිනවා:

  • ඔබේ රේඛා ප්රමාණවත් තරම් දිගු නම් (අක්ෂර 100-200 සිට). මෙම අවස්ථාවේදී, ඔබ deflate වැනි සම්පීඩන ඇල්ගොරිතම භාවිතා කිරීම ගැන සිතා බැලිය යුතුය.
  • ඔබට අවශ්ය නම් ASCII විනිවිදභාවය, එනම්, කේතනය කරන ලද අනුපිළිවෙලෙහි මුල් තන්තුවෙහි නොතිබූ ASCII කේත අඩංගු නොවීම ඔබට වැදගත් වේ. තෙවන පාර්ශවීය API සමඟ අන්තර් ක්‍රියා කරන විට (උදාහරණයක් ලෙස, දත්ත සමුදායක් සමඟ වැඩ කරන විට), ඔබ කේතීකරණ ප්‍රතිඵලය තන්තු ලෙස නොව, වියුක්ත බයිට් කට්ටලයක් ලෙස ලබා දෙන්නේ නම්, මේ සඳහා අවශ්‍යතාවය මඟ හැරිය හැක. එසේ නොමැතිනම්, ඔබ අනපේක්ෂිත දුර්වලතා ලබා ගැනීමේ අවදානමක් ඇත.
  • ඔබට අත්තනෝමතික ඕෆ්සෙට් එකකදී අක්ෂර මායිම් ඉක්මනින් සොයා ගැනීමට අවශ්‍ය නම් (උදාහරණයක් ලෙස, පේළියක කොටසක් හානි වූ විට). මෙය සිදු කළ හැකිය, නමුත් ආරම්භයේ සිට රේඛාව ස්කෑන් කිරීම (හෝ පෙර කොටසේ විස්තර කර ඇති වෙනස් කිරීම යෙදීම) පමණි.
  • ඔබට ඉක්මනින් නූල් වල අන්තර්ගතය මත මෙහෙයුම් සිදු කිරීමට අවශ්‍ය නම් (ඒවා වර්ග කරන්න, ඒවායේ උප තන්තු සොයන්න, සම්බන්ධ කරන්න). මෙයට මුලින්ම තන්තු විකේතනය කිරීම අවශ්‍ය වේ, එබැවින් UTF-C මෙම අවස්ථා වලදී UTF-8 ට වඩා මන්දගාමී වනු ඇත (නමුත් සම්පීඩන ඇල්ගොරිතම වලට වඩා වේගවත්). එකම තන්තුව සෑම විටම එකම ආකාරයෙන් කේතනය කර ඇති බැවින්, විකේතනය පිළිබඳ නිවැරදි සංසන්දනය අවශ්‍ය නොවන අතර බයිට්-බයිට් පදනමින් සිදු කළ හැක.

යාවත්කාලීනය: පරිශීලකයා ටියෝමිච් පහත අදහස් වල UTF-C හි අදාළතා සීමාවන් ඉස්මතු කරන ප්‍රස්ථාරයක් පළ කළේය. එය පෙන්නුම් කරන්නේ UTF-C සාමාන්‍ය කාර්ය සම්පීඩන ඇල්ගොරිතමයකට වඩා (LZW හි වෙනසක්) ඇසුරුම් කළ නූල කෙටි වන තාක් කාර්යක්ෂම බවයි. අක්ෂර ~140 (කෙසේ වෙතත්, සංසන්දනය එක් පාඨයක් මත සිදු කරන ලද බව මම සටහන් කරමි; අනෙකුත් භාෂා සඳහා ප්රතිඵලය වෙනස් විය හැක).
තවත් බයිසිකලයක්: අපි යුනිකෝඩ් නූල් ගබඩා කරන්නේ UTF-30 ට වඩා 60-8% වැඩිය.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න