மற்றொரு பைக்: யூனிகோட் சரங்களை UTF-30ஐ விட 60-8% அதிகமாக சேமிக்கிறோம்

மற்றொரு பைக்: யூனிகோட் சரங்களை UTF-30ஐ விட 60-8% அதிகமாக சேமிக்கிறோம்

நீங்கள் ஒரு டெவலப்பர் மற்றும் குறியாக்கத்தைத் தேர்ந்தெடுக்கும் பணியை எதிர்கொண்டால், யூனிகோட் எப்போதும் சரியான தீர்வாக இருக்கும். குறிப்பிட்ட பிரதிநிதித்துவ முறை சூழலைப் பொறுத்தது, ஆனால் பெரும்பாலும் இங்கே உலகளாவிய பதில் உள்ளது - UTF-8. இதில் உள்ள நல்ல விஷயம் என்னவென்றால், அனைத்து யூனிகோட் எழுத்துக்களையும் செலவில்லாமல் பயன்படுத்த இது உங்களை அனுமதிக்கிறது அதிகம் பெரும்பாலான சந்தர்ப்பங்களில் நிறைய பைட்டுகள். உண்மை, லத்தீன் எழுத்துக்களை விட அதிகமாக பயன்படுத்தும் மொழிகளுக்கு, "அதிகமாக இல்லை" என்பது குறைந்தபட்சம் ஒரு எழுத்துக்கு இரண்டு பைட்டுகள். கிடைக்கக்கூடிய 256 எழுத்துகளுக்கு மட்டுமே நம்மைக் கட்டுப்படுத்தும் வரலாற்றுக்கு முந்தைய குறியாக்கங்களுக்குத் திரும்பாமல் சிறப்பாகச் செய்ய முடியுமா?

இந்த கேள்விக்கு பதிலளிப்பதற்கும், UTF-8 இல் உள்ள பணிநீக்கத்தைச் சேர்க்காமல் உலகின் பெரும்பாலான மொழிகளில் வரிகளைச் சேமிக்க அனுமதிக்கும் ஒப்பீட்டளவில் எளிமையான வழிமுறையை செயல்படுத்துவதற்கும் எனது முயற்சியைப் பற்றி உங்களுக்குத் தெரிந்துகொள்ள நான் கீழே முன்மொழிகிறேன்.

மறுப்பு. நான் உடனடியாக சில முக்கியமான முன்பதிவுகளைச் செய்கிறேன்: விவரிக்கப்பட்ட தீர்வு UTF-8 க்கு உலகளாவிய மாற்றாக வழங்கப்படவில்லை, இது வழக்குகளின் குறுகிய பட்டியலில் மட்டுமே பொருத்தமானது (அவற்றில் மேலும் கீழே), மேலும் மூன்றாம் தரப்பு API களுடன் (அதைப் பற்றி அறியாதவர்கள்) தொடர்பு கொள்ள எந்த சந்தர்ப்பத்திலும் இதைப் பயன்படுத்தக்கூடாது. பெரும்பாலும், பொது-நோக்க சுருக்க வழிமுறைகள் (உதாரணமாக, deflate) பெரிய அளவிலான உரை தரவுகளின் சிறிய சேமிப்பிற்கு ஏற்றது. கூடுதலாக, ஏற்கனவே எனது தீர்வை உருவாக்கும் செயல்பாட்டில், யூனிகோடில் ஏற்கனவே உள்ள தரநிலையைக் கண்டேன், இது அதே சிக்கலை தீர்க்கிறது - இது சற்றே சிக்கலானது (மற்றும் பெரும்பாலும் மோசமானது), ஆனால் இன்னும் இது ஏற்றுக்கொள்ளப்பட்ட தரநிலையாகும், அது மட்டும் அல்ல. முழங்காலில் ஒன்றாக. அவரைப் பற்றியும் சொல்கிறேன்.

யூனிகோட் மற்றும் UTF-8 பற்றி

தொடங்குவதற்கு, அது என்ன என்பதைப் பற்றி சில வார்த்தைகள் யுனிகோட் и யுடிஎஃப் 8.

உங்களுக்கு தெரியும், 8-பிட் குறியாக்கங்கள் பிரபலமாக இருந்தன. அவற்றுடன், எல்லாம் எளிமையானது: 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).

பிறகு ஏன் புதிதாக ஒன்றைக் கண்டுபிடிக்க வேண்டும்?

அதே நேரத்தில், சில சமயங்களில், டிப்ளேட் போன்ற சுருக்க அல்காரிதம்கள் சரியாகப் பொருந்தாத சூழ்நிலைகள் உள்ளன, ஆனால் நீங்கள் சரங்களின் சிறிய சேமிப்பகத்தை அடைய விரும்புகிறீர்கள். தனிப்பட்ட முறையில், கட்டிடம் பற்றி யோசிக்கும் போது நான் இந்த சிக்கலை எதிர்கொண்டேன் சுருக்கப்பட்ட முன்னொட்டு மரம் தன்னிச்சையான மொழிகளில் உள்ள சொற்கள் உட்பட ஒரு பெரிய அகராதிக்கு. ஒருபுறம், ஒவ்வொரு வார்த்தையும் மிகவும் சிறியது, எனவே அதை சுருக்குவது பயனற்றதாக இருக்கும். மறுபுறம், நான் கருதிய மர செயலாக்கம், சேமிக்கப்பட்ட சரத்தின் ஒவ்வொரு பைட்டும் தனித்தனி மர உச்சியை உருவாக்கும் வகையில் வடிவமைக்கப்பட்டுள்ளது, எனவே அவற்றின் எண்ணிக்கையைக் குறைப்பது மிகவும் பயனுள்ளதாக இருந்தது. என் நூலகத்தில் Az.js (உள்ளபடி பைமார்பி2, இது அடிப்படையாகக் கொண்டது) இதேபோன்ற சிக்கலை எளிமையாக தீர்க்க முடியும் - சரங்கள் நிரம்பியுள்ளன Dawg-அகராதி, அங்கு சேமிக்கப்பட்டுள்ளது நல்ல பழைய CP1251. ஆனால், புரிந்துகொள்வது எளிது, இது வரையறுக்கப்பட்ட எழுத்துக்களுக்கு மட்டுமே நன்றாக வேலை செய்கிறது - சீன மொழியில் ஒரு வரியை அத்தகைய அகராதியில் சேர்க்க முடியாது.

தனித்தனியாக, அத்தகைய தரவு கட்டமைப்பில் UTF-8 ஐப் பயன்படுத்தும் போது எழும் ஒரு விரும்பத்தகாத நுணுக்கத்தை நான் கவனிக்க விரும்புகிறேன். ஒரு எழுத்தை இரண்டு பைட்டுகளாக எழுதும்போது, ​​அதன் எண்ணுடன் தொடர்புடைய பிட்கள் வரிசையாக வராமல், ஒரு ஜோடி பிட்களால் பிரிக்கப்பட்டிருப்பதை மேலே உள்ள படம் காட்டுகிறது. 10 மத்தியில்: 110xxxxx 10xxxxxx. இதன் காரணமாக, இரண்டாவது பைட்டின் கீழ் 6 பிட்கள் எழுத்துக் குறியீட்டில் (அதாவது, ஒரு மாற்றம் ஏற்படும். 1011111110000000), பின்னர் முதல் பைட் கூட மாறுகிறது. "p" என்ற எழுத்து பைட்டுகளால் குறிக்கப்படுகிறது என்று மாறிவிடும் 0xD0 0xBF, மற்றும் அடுத்த "r" ஏற்கனவே உள்ளது 0xD1 0x80. முன்னொட்டு மரத்தில், இது பெற்றோர் முனையை இரண்டாகப் பிரிக்க வழிவகுக்கிறது - முன்னொட்டுக்கு ஒன்று 0xD0, மற்றும் மற்றொன்று 0xD1 (முழு சிரிலிக் எழுத்துக்களையும் இரண்டாவது பைட் மூலம் மட்டுமே குறியாக்கம் செய்ய முடியும்).

எனக்கு என்ன கிடைத்தது

இந்த சிக்கலை எதிர்கொண்ட நான், பிட்களுடன் கேம்களை விளையாடுவதைப் பயிற்சி செய்ய முடிவு செய்தேன், அதே நேரத்தில் யூனிகோட் கட்டமைப்பைப் பற்றி கொஞ்சம் நன்றாகப் பழகினேன். இதன் விளைவாக UTF-C குறியாக்க வடிவம் ("C" க்கான கச்சிதமான), இது ஒரு குறியீடு புள்ளிக்கு 3 பைட்டுகளுக்கு மேல் செலவழிக்காது, மேலும் பெரும்பாலும் உங்களை மட்டுமே செலவழிக்க அனுமதிக்கிறது முழு குறியிடப்பட்ட வரிக்கும் ஒரு கூடுதல் பைட். இது பல ASCII அல்லாத எழுத்துக்களில் இத்தகைய குறியாக்கம் மாறுகிறது. UTF-30 ஐ விட 60-8% அதிக கச்சிதமானது.

படிவத்தில் என்கோடிங் மற்றும் டிகோடிங் அல்காரிதம்களை செயல்படுத்துவதற்கான உதாரணங்களை நான் வழங்கியுள்ளேன் ஜாவாஸ்கிரிப்ட் மற்றும் கோ நூலகங்கள், உங்கள் குறியீட்டில் அவற்றை நீங்கள் சுதந்திரமாகப் பயன்படுத்தலாம். ஆனால் இந்த வடிவம் ஒரு "சைக்கிள்" ஆகவே உள்ளது என்பதை நான் இன்னும் வலியுறுத்துவேன், அதைப் பயன்படுத்த நான் பரிந்துரைக்கவில்லை. உங்களுக்கு ஏன் இது தேவை என்பதை உணராமல். இது இன்னும் தீவிரமான "UTF-8 இன் முன்னேற்றம்" என்பதை விட ஒரு பரிசோதனையாகும். ஆயினும்கூட, அங்குள்ள குறியீடு நேர்த்தியாகவும், சுருக்கமாகவும், அதிக எண்ணிக்கையிலான கருத்துகள் மற்றும் சோதனைக் கவரேஜுடன் எழுதப்பட்டுள்ளது.

மற்றொரு பைக்: யூனிகோட் சரங்களை UTF-30ஐ விட 60-8% அதிகமாக சேமிக்கிறோம்
சோதனை முடிவுகள் மற்றும் UTF-8 உடன் ஒப்பிடுதல்

நானும் செய்தேன் டெமோ பக்கம், நீங்கள் அல்காரிதத்தின் செயல்திறனை மதிப்பீடு செய்யக்கூடிய இடத்தில், அதன் கொள்கைகள் மற்றும் மேம்பாட்டு செயல்முறை பற்றி நான் உங்களுக்கு மேலும் கூறுவேன்.

தேவையற்ற பிட்களை நீக்குதல்

நான் 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 குறியீடுகளை விட இது இன்னும் குறிப்பிடத்தக்க அளவில் பெரியதாக உள்ளது, மிகவும் பொதுவான மொழிகள் இன்னும் பொருந்துகின்றன, மிகவும் குறிப்பிடத்தக்க இழப்பு வெளியேறிவிட்டது ஹிரகனா и கடகனா, ஜப்பானியர்கள் சோகமாக இருக்கிறார்கள்.

இந்த புதிய குறியீடு என்ன? 11xxxxxx? இது 64 எழுத்துக்கள் கொண்ட சிறிய "ஸ்டாஷ்" ஆகும், இது எங்கள் முக்கிய எழுத்துக்களை நிறைவு செய்கிறது, எனவே நான் அதை துணை என்று அழைத்தேன் (துணை) எழுத்துக்கள். தற்போதைய எழுத்துக்களை மாற்றும் போது, ​​பழைய எழுத்துக்களின் ஒரு பகுதி துணை ஆகிறது. எடுத்துக்காட்டாக, நாங்கள் ASCII இலிருந்து Cyrillic க்கு மாறினோம் - ஸ்டாஷில் இப்போது 64 எழுத்துகள் உள்ளன லத்தீன் எழுத்துக்கள், எண்கள், இடம் மற்றும் கமா (ஆஸ்கி அல்லாத நூல்களில் அடிக்கடி செருகல்கள்). மீண்டும் ASCII க்கு மாறவும் - மேலும் சிரிலிக் எழுத்துக்களின் முக்கிய பகுதி துணை எழுத்துக்களாக மாறும்.

இரண்டு எழுத்துக்களுக்கான அணுகலுக்கு நன்றி, எழுத்துக்களை மாற்றுவதற்கு குறைந்த செலவில் அதிக எண்ணிக்கையிலான உரைகளை நாம் கையாள முடியும் (நிறுத்தக்குறிகள் பெரும்பாலும் ASCII க்கு திரும்புவதற்கு வழிவகுக்கும், ஆனால் அதன் பிறகு கூடுதல் எழுத்துக்களில் இருந்து ASCII அல்லாத பல எழுத்துக்களைப் பெறுவோம். மீண்டும் மாறுகிறது).

போனஸ்: துணை எழுத்துக்களின் முன்னொட்டு 11xxxxxx மற்றும் அதன் ஆரம்ப ஆஃப்செட்டைத் தேர்ந்தெடுப்பது 0xC0, CP1252 உடன் பகுதி இணக்கத்தன்மையைப் பெறுகிறோம். வேறு வார்த்தைகளில் கூறுவதானால், CP1252 இல் குறியிடப்பட்ட பல (ஆனால் அனைத்துமே இல்லை) மேற்கத்திய ஐரோப்பிய உரைகள் UTF-C இல் ஒரே மாதிரியாக இருக்கும்.

இருப்பினும், இங்கே ஒரு சிரமம் எழுகிறது: முக்கிய எழுத்துக்களில் இருந்து துணை ஒன்றை எவ்வாறு பெறுவது? நீங்கள் அதே ஆஃப்செட்டை விட்டுவிடலாம், ஆனால் - ஐயோ - இங்கே யூனிகோட் அமைப்பு ஏற்கனவே எங்களுக்கு எதிராக விளையாடுகிறது. பெரும்பாலும் எழுத்துக்களின் முக்கிய பகுதி தொகுதியின் தொடக்கத்தில் இல்லை (எடுத்துக்காட்டாக, ரஷ்ய தலைநகரான "A" குறியீட்டைக் கொண்டுள்ளது. 0x0410, சிரிலிக் தொகுதி தொடங்கினாலும் 0x0400) எனவே, முதல் 64 எழுத்துக்களை ஸ்டாஷிற்குள் எடுத்தால், எழுத்துக்களின் வால் பகுதிக்கான அணுகலை நாம் இழக்க நேரிடும்.

இந்தச் சிக்கலைச் சரிசெய்ய, வெவ்வேறு மொழிகளுடன் தொடர்புடைய சில தொகுதிகளை நான் கைமுறையாகச் சென்று, அவற்றுக்கான முதன்மையான துணை எழுத்துக்களின் ஆஃப்செட்டைக் குறிப்பிட்டேன். லத்தீன் எழுத்துக்கள், விதிவிலக்காக, பொதுவாக அடிப்படை64 போன்று மறுவரிசைப்படுத்தப்பட்டது.

மற்றொரு பைக்: யூனிகோட் சரங்களை UTF-30ஐ விட 60-8% அதிகமாக சேமிக்கிறோம்

இறுதி தொடுதல்கள்

வேறு எங்கு எதையாவது மேம்படுத்தலாம் என்று இறுதியாக சிந்திப்போம்.

வடிவம் என்பதை கவனத்தில் கொள்ளவும் 101xxxxx xxxxxxxx xxxxxxxx வரை எண்களை குறியாக்கம் செய்ய உங்களை அனுமதிக்கிறது 0x1FFFFF, மற்றும் யூனிகோட் முன்னதாக முடிவடைகிறது, மணிக்கு 0x10FFFF. வேறு வார்த்தைகளில் கூறுவதானால், கடைசி குறியீட்டு புள்ளி இவ்வாறு குறிப்பிடப்படும் 10110000 11111111 11111111. எனவே, முதல் பைட் என்றால் வடிவம் என்று சொல்லலாம் 1011xxxx (எங்கே xxxx 0 ஐ விட பெரியது), பின்னர் அது வேறு எதையாவது குறிக்கிறது. எடுத்துக்காட்டாக, ஒரு பைட்டில் குறியாக்கத்திற்கு தொடர்ந்து கிடைக்கும் மேலும் 15 எழுத்துக்களை நீங்கள் சேர்க்கலாம், ஆனால் நான் அதை வித்தியாசமாக செய்ய முடிவு செய்தேன்.

இப்போது மூன்று பைட்டுகள் தேவைப்படும் யூனிகோட் தொகுதிகளைப் பார்ப்போம். அடிப்படையில், ஏற்கனவே குறிப்பிட்டுள்ளபடி, இவை சீன எழுத்துக்கள் - ஆனால் அவர்களுடன் எதையும் செய்வது கடினம், அவற்றில் 21 ஆயிரம் உள்ளன. ஆனால் ஹிரகனா மற்றும் கடகனாவும் அங்கு பறந்தன - மேலும் அவற்றில் பல இல்லை, இருநூறுக்கும் குறைவானவை. மேலும், நாங்கள் ஜப்பானியர்களை நினைவில் வைத்திருந்ததால், ஈமோஜிகளும் உள்ளன (உண்மையில், அவை யூனிகோடில் பல இடங்களில் சிதறிக்கிடக்கின்றன, ஆனால் முக்கிய தொகுதிகள் வரம்பில் உள்ளன 0x1F300 - 0x1FBFF) இப்போது பல குறியீடு புள்ளிகளில் இருந்து ஒரே நேரத்தில் அசெம்பிள் செய்யப்பட்ட ஈமோஜிகள் உள்ளன என்பதை நீங்கள் நினைத்தால் (உதாரணமாக, ஈமோஜிமற்றொரு பைக்: யூனிகோட் சரங்களை UTF-30ஐ விட 60-8% அதிகமாக சேமிக்கிறோம் 7 குறியீடுகளைக் கொண்டுள்ளது!), பிறகு ஒவ்வொன்றிலும் மூன்று பைட்டுகள் (7×3 = 21 பைட்டுகள் ஒரு ஐகானுக்காக, ஒரு கனவுக்காக) செலவிடுவது முற்றிலும் அவமானமாகிவிடும்.

எனவே, எமோஜி, ஹிரகனா மற்றும் கட்டகானா ஆகியவற்றுடன் தொடர்புடைய சில தேர்ந்தெடுக்கப்பட்ட வரம்புகளைத் தேர்ந்தெடுத்து, அவற்றை ஒரு தொடர்ச்சியான பட்டியலில் மறுபெயரிட்டு, மூன்றிற்குப் பதிலாக இரண்டு பைட்டுகளாக குறியாக்கம் செய்கிறோம்:

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 இன் ஒப்பீட்டளவில் எளிமையான செயலாக்கத்தை ஜாவாஸ்கிரிப்ட்டுக்கு மாற்றினேன் - குறியீட்டின் அளவைப் பொறுத்தவரை இது எனது UTF-C உடன் ஒப்பிடத்தக்கதாக மாறியது, ஆனால் சில சந்தர்ப்பங்களில் விளைவு பத்து சதவிகிதம் மோசமாக இருந்தது (சில நேரங்களில் அது அதை விட அதிகமாக இருக்கலாம், ஆனால் அதிகம் இல்லை). எடுத்துக்காட்டாக, ஹீப்ரு மற்றும் கிரேக்க மொழிகளில் உள்ள உரைகள் 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 பைட்டுகள் மட்டுமே எடையுள்ளதாக இருக்கும் (நிச்சயமாக சார்புகள் எதுவும் இல்லை). நான் மேலே குறிப்பிட்டுள்ளபடி, அவளுடைய வேலையைக் காணலாம் டெமோ பக்கம் (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

கருத்தைச் சேர்