{"id":95911,"date":"2020-10-05T01:42:09","date_gmt":"2020-10-04T23:42:09","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/eshhyo-odin-velosiped-hranim-yunikodnye-stroki-na-30-60-kompaktnee-chem-utf-8"},"modified":"2020-10-05T01:42:09","modified_gmt":"2020-10-04T23:42:09","slug":"eshhyo-odin-velosiped-hranim-yunikodnye-stroki-na-30-60-kompaktnee-chem-utf-8","status":"publish","type":"post","link":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/eshhyo-odin-velosiped-hranim-yunikodnye-stroki-na-30-60-kompaktnee-chem-utf-8","title":{"rendered":"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/56c10bad377127b711bdb204ee300772.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHa fejleszt\u0151 vagy, \u00e9s el\u0151ttad \u00e1ll a karakterk\u00f3dol\u00e1s kiv\u00e1laszt\u00e1s\u00e1nak feladata, szinte mindig a Unicode a helyes megold\u00e1s. A konkr\u00e9t megjelen\u00edt\u00e9si m\u00f3d a kontextust\u00f3l f\u00fcgg, de a leggyakrabban itt is van egy univerz\u00e1lis v\u00e1lasz \u2014 UTF-8. Ez az\u00e9rt j\u00f3, mert lehet\u0151v\u00e9 teszi a Unicode \u00f6sszes karakter\u00e9nek haszn\u00e1lat\u00e1t, an\u00e9lk\u00fcl, hogy <em>t\u00fal<\/em> sok byte-ot k\u00f6lten\u00e9nk a legt\u00f6bb esetben. Az igaz, hogy a nemcsak latin bet\u0171s nyelvek eset\u00e9ben a \"nem t\u00fal sok\" az legal\u00e1bb <strong>k\u00e9t byte karakterenk\u00e9nt<\/strong>. Van enn\u00e9l jobb megold\u00e1s, an\u00e9lk\u00fcl, hogy visszat\u00e9rn\u00e9nk a prehistorikus k\u00f3dol\u00e1sokhoz, amelyek csup\u00e1n 256 el\u00e9rhet\u0151 karakterrel korl\u00e1toznak minket?<\/p>\n<p>Al\u00e1bb javaslom, hogy ismerkedj meg azzal az pr\u00f3b\u00e1lkoz\u00e1sommal, hogy v\u00e1laszt adjak erre a k\u00e9rd\u00e9sre, \u00e9s egy viszonylag egyszer\u0171 algoritmus megval\u00f3s\u00edt\u00e1s\u00e1val, amely lehet\u0151v\u00e9 teszi a sz\u00f6vegek t\u00e1rol\u00e1s\u00e1t a vil\u00e1g legt\u00f6bb nyelv\u00e9n, an\u00e9lk\u00fcl, hogy azt a felesleges t\u00f6bbletet hozz\u00e1adn\u00e1nk, ami az UTF-8-ban van.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><i>Nyilatkozat.<\/i> Azonnal szeretn\u00e9k n\u00e9h\u00e1ny fontos pontos\u00edt\u00e1st tenni: <strong>a megold\u00e1s nem javasolt univerz\u00e1lis helyettes\u00edt\u0151k\u00e9nt az UTF-8 sz\u00e1m\u00e1ra<\/strong>, csup\u00e1n egy sz\u0171k esetek list\u00e1j\u00e1ra alkalmazhat\u00f3 (err\u0151l lentebb), \u00e9s semmik\u00e9ppen sem haszn\u00e1lhat\u00f3 harmadik f\u00e9lt\u0151l sz\u00e1rmaz\u00f3 API-kkal val\u00f3 interakci\u00f3ra (amelyek nem is tudnak r\u00f3la). Legt\u00f6bbsz\u00f6r a nagy mennyis\u00e9g\u0171 sz\u00f6veges adat kompakt t\u00e1rol\u00e1s\u00e1hoz \u00e1ltal\u00e1nos c\u00e9l\u00fa t\u00f6m\u00f6r\u00edt\u00e9si algoritmusok, p\u00e9ld\u00e1ul a deflate, jobban megfelelnek. Ezen k\u00edv\u00fcl, m\u00e1r a megold\u00e1som kidolgoz\u00e1sa sor\u00e1n tal\u00e1ltam egy l\u00e9tez\u0151 szabv\u00e1nyt mag\u00e1ban a Unicode-ban, amely ugyanazt a feladatot oldja meg \u2014 valamivel bonyolultabb (\u00e9s gyakran rosszabb), de mindenk\u00e9ppen egy elfogadott standard, nem egy \u00f6sszerakott kezdeti megold\u00e1s. Err\u0151l is besz\u00e9lni fogok.<\/p>\n<h2>A Unicode-r\u00f3l \u00e9s az UTF-8-r\u00f3l<\/h2>\n<p>\nEl\u0151sz\u00f6r is \u2014 n\u00e9h\u00e1ny sz\u00f3 arr\u00f3l, hogy mi is az a <strong>Unicode<\/strong> \u00e9s <strong>UTF-8<\/strong>.<\/p>\n<p>Mint tudjuk, kor\u00e1bban a 8 bites k\u00f3dol\u00e1sok n\u00e9pszer\u0171ek voltak. Itt minden egyszer\u0171 volt: 256 karaktert lehetett sz\u00e1mozni 0-t\u00f3l 255-ig, a 0-t\u00f3l 255-ig terjed\u0151 sz\u00e1mok nyilv\u00e1nval\u00f3an egy byte-ban \u00e1br\u00e1zolhat\u00f3k. Ha visszat\u00e9r\u00fcnk a leg\u0151sibb gy\u00f6kerekhez, akkor az ASCII k\u00f3dol\u00e1s val\u00f3ban csak 7 bitre korl\u00e1toz\u00f3dik, \u00edgy a legfels\u0151 bit a byte-j\u00e1nak \u00e1br\u00e1zol\u00e1s\u00e1ban nulla, \u00e9s a legt\u00f6bb 8 bites k\u00f3dol\u00e1s kompatibilis vele (csak a \"fels\u0151\" r\u00e9szen k\u00fcl\u00f6nb\u00f6znek, ahol a legfels\u0151 bit egy).<\/p>\n<p>Mi k\u00fcl\u00f6nb\u00f6zteti meg teh\u00e1t ezeket a k\u00f3dol\u00e1sokat a Unicode-t\u00f3l, \u00e9s mi\u00e9rt kapcsol\u00f3dik hozz\u00e1juk azonnal sz\u00e1mos konkr\u00e9t megjelen\u00edt\u00e9s \u2014 UTF-8, UTF-16 (BE \u00e9s LE), UTF-32? Vizsg\u00e1ljuk meg l\u00e9p\u00e9sr\u0151l l\u00e9p\u00e9sre.<\/p>\n<p>A Unicode alapvet\u0151 szabv\u00e1nya csak a karakterek (\u00e9s bizonyos esetekben a karakterek k\u00fcl\u00f6n komponensei) \u00e9s azok sz\u00e1m\u00e1nak megfelel\u0151s\u00e9g\u00e9t \u00edrja le. \u00c9s a szabv\u00e1nyban a lehets\u00e9ges sz\u00e1mok sz\u00e1ma nagyon nagy \u2014 <code><b>0x00<\/b><\/code> t\u00f3l <code><b>0x10FFFF<\/b><\/code> (1 114 112 darab). Ha egy ilyen tartom\u00e1nyban akarn\u00e1nk sz\u00e1mot t\u00e1rolni egy v\u00e1ltoz\u00f3ban, sem 1, sem 2 b\u00e1jt nem lenne elegend\u0151. Mivel a h\u00e1rom b\u00e1jtos sz\u00e1mokkal val\u00f3 munka nem igaz\u00e1n optimaliz\u00e1lt a processzoraink sz\u00e1m\u00e1ra, k\u00e9nytelenek lenn\u00e9nk n\u00e9gy b\u00e1jtot haszn\u00e1lni egyetlen karakterre! Ez a UTF-32, de \u00e9ppen emiatt a \u201epazarl\u00e1s\u201d miatt ez a form\u00e1tum nem n\u00e9pszer\u0171.<\/p>\n<p>Szerencs\u00e9re a Unicode-on bel\u00fcli karakterek rendez\u00e9se nem v\u00e9letlenszer\u0171. Az \u00f6sszes karakter 17 \u201e<em>s\u00edkra<\/em>van felosztva, amelyek mindegyike 65536 (<code><b>0x10000<\/b><\/code>) \u00ab<em>k\u00f3dpontot<\/em>). A \u201ek\u00f3dpont\u201d kifejez\u00e9s itt egyszer\u0171en <em>a karakter sz\u00e1ma<\/em>, amelyet a Unicode rendelt hozz\u00e1. De, ahogy m\u00e1r eml\u00edtettem, a Unicode-ban nemcsak a k\u00fcl\u00f6n\u00e1ll\u00f3 karakterek, hanem azok komponensei \u00e9s seg\u00e9djelek sz\u00e1mozva vannak (\u00e9s n\u00e9ha semmi nem felel meg a sz\u00e1mnak \u2014 lehet, hogy egy id\u0151re, de ez sz\u00e1munkra nem l\u00e9nyeges), ez\u00e9rt helyesebb mindig a sz\u00e1mok sz\u00e1m\u00e1r\u00f3l besz\u00e9lni, nem a karakterek sz\u00e1m\u00e1r\u00f3l. Azonban a tov\u00e1bbiakban a t\u00f6m\u00f6rs\u00e9g kedv\u00e9\u00e9rt gyakran fogom haszn\u00e1lni a \u201ekarakter\u201d sz\u00f3t, utalva a \u201ek\u00f3dpontra\u201d.<\/p>\n<p><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/7ad84b571a8025582fdbc3db956cb3b0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>A Unicode s\u00edkjai. Ahogy l\u00e1that\u00f3, a legt\u00f6bb (4-13. s\u00edk) m\u00e9g mindig nem haszn\u00e1lva.<\/i><\/p>\n<p>A legcsod\u00e1latosabb az, hogy az \u00f6sszes l\u00e9nyeg a nulladik s\u00edkban tal\u00e1lhat\u00f3, ezt h\u00edvj\u00e1k &quot;<em>Basic Multilingual Plane<\/em>&quot;. Ha a sor tartalmaz sz\u00f6veget valamelyik modern nyelven (bele\u00e9rtve a k\u00ednait is), akkor nem l\u00e9phet \u00e1t ezen a s\u00edkon. De a t\u00f6bbi Unicode r\u00e9sz\u00e9t sem lehet lev\u00e1gni \u2014 p\u00e9ld\u00e1ul az emojik f\u0151leg a k\u00f6vetkez\u0151 s\u00edk v\u00e9g\u00e9n tal\u00e1lhat\u00f3k, &quot;<em>Supplementary Multilingual Plane<\/em>&quot; (ez kiterjed arra, hogy <code><b>0x10000<\/b><\/code> t\u00f3l <code><b>0x1FFFF<\/b><\/code>). Ez\u00e9rt az UTF-16 \u00fagy m\u0171k\u00f6dik, hogy minden karakter, amely beleesik ide, \u201eahogy van\u201d van k\u00f3dolva, a megfelel\u0151 k\u00f3dj\u00e1t haszn\u00e1lva. Azonban a sz\u00e1mok egy r\u00e9sze ebben a tartom\u00e1nyban egy\u00e1ltal\u00e1n nem konkr\u00e9t karaktereket jel\u00f6l, hanem arra utal, hogy a p\u00e1ros b\u00e1jt ut\u00e1n m\u00e9g egyet kell figyelembe venni \u2014 ha ezeket a n\u00e9gy b\u00e1jtot egy\u00fctt kombin\u00e1lva, a Unicode teljes enged\u00e9lyezett tartom\u00e1ny\u00e1t lefed\u0151 sz\u00e1mot kapunk. Ezt a form\u00e1tumot \u201eszurrog\u00e1tp\u00e1roknak\u201d nevezik \u2014 lehet, hogy hallott m\u00e1r r\u00f3luk. <em>Basic Multilingual Plane<\/em>, a \"t\u00e9nylegesen\" k\u00f3dolj\u00e1k, a megfelel\u0151 k\u00e9tt\u00e1bl\u00e1s sz\u00e1mmal. Azonban a sz\u00e1mok egy r\u00e9sze ebben a tartom\u00e1nyban nem k\u00e9pvisel konkr\u00e9t karaktereket, hanem arra utal, hogy az ezen b\u00e1jt-p\u00e1r ut\u00e1n egy m\u00e1sikat is figyelembe kell venni \u2014 az \u00e9rt\u00e9kek n\u00e9gy b\u00e1jt \u00f6sszevon\u00e1s\u00e1val egy olyan sz\u00e1mot kapunk, amely lefedi a Unicode megengedett teljes tartom\u00e1ny\u00e1t. Ezt a reprezent\u00e1ci\u00f3t \"szurre\u00e1lis p\u00e1roknak\" h\u00edvj\u00e1k \u2014 lehet, hogy hallott\u00e1l r\u00f3luk.<\/p>\n<p>\u00cdgy a UTF-16 k\u00e9t vagy (nagyon ritka esetekben) n\u00e9gy b\u00e1jtot ig\u00e9nyel egy \u201ek\u00f3dpont\u201d eset\u00e9n. Ez jobb, mint folyamatosan n\u00e9gy b\u00e1jt haszn\u00e1lni, de a latin \u00e1b\u00e9c\u00e9 (\u00e9s m\u00e1s ASCII karakterek) ezen a k\u00f3dol\u00e1son f\u00e9l helyet foglal el z\u00e9r\u00f3kkal. A UTF-8 c\u00e9lja ennek orvosl\u00e1sa: az ASCII itt csup\u00e1n egy b\u00e1jt; a k\u00f3dok <code><b>0x80<\/b><\/code> t\u00f3l <code><b>0x7FF<\/b><\/code> \u2014 k\u00e9t b\u00e1jt; a <code><b>0x800<\/b><\/code> t\u00f3l <code><b>0xFFFF<\/b><\/code> \u2014 h\u00e1rom, m\u00edg a <code><b>0x10000<\/b><\/code> t\u00f3l <code><b>0x10FFFF<\/b><\/code> \u2014 n\u00e9gy. Egyr\u00e9szt a latin \u00e1b\u00e9c\u00e9 j\u00f3l j\u00e1rt: visszanyerte az ASCII-kompatibilit\u00e1st, \u00e9s az eloszl\u00e1s egyenletesebben \u201eelken\u0151dik\u201d 1 \u00e9s 4 b\u00e1jt k\u00f6z\u00f6tt. De m\u00e1s \u00e1b\u00e9c\u00e9k, sajnos, nem profit\u00e1lnak a UTF-8-b\u00f3l a UTF-16-hoz k\u00e9pest, \u00e9s sok esetben m\u00e1r h\u00e1rom b\u00e1jtot ig\u00e9nyelnek a k\u00e9t helyett \u2014 a k\u00e9tb\u00e1jtos r\u00f6gz\u00edt\u00e9s \u00e1ltal lefedett tartom\u00e1ny 32-szer zsugorodott, <code><b>0xFFFF<\/b><\/code> t\u00f3l <code><b>0x7FF<\/b><\/code>, \u00e9s m\u00e1r nem tartalmaz sem k\u00ednai, sem p\u00e9ld\u00e1ul gr\u00faz karaktereket. A cirill \u00e9s m\u00e9g \u00f6t m\u00e1sik \u00e1b\u00e9c\u00e9 \u2014 &nbsp;hurra \u2014 &nbsp;szerencs\u00e9s, 2 b\u00e1jt karakterenk\u00e9nt.<\/p>\n<p>Mi\u00e9rt van ez \u00edgy? N\u00e9zz\u00fck meg, hogyan k\u00e9pviseli a UTF-8 a karakterk\u00f3dokat:<br \/>\n<img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/4ef4fe9e949cd75295c45c053dbca6d3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nK\u00f6zvetlen\u00fcl a sz\u00e1mok reprezent\u00e1l\u00e1s\u00e1hoz itt biteket haszn\u00e1lnak, amelyeket a <code><b>x<\/b><\/code>jel\u00f6l. L\u00e1that\u00f3, hogy a k\u00e9tb\u00e1jtos r\u00f6gz\u00edt\u00e9sben csup\u00e1n 11 bit van (a 16-b\u00f3l). A vezet\u0151 bitek itt csak seg\u00e9dfunkci\u00f3t l\u00e1tnak el. A n\u00e9gyb\u00e1jtos r\u00f6gz\u00edt\u00e9s eset\u00e9ben pedig a k\u00f3dpont sz\u00e1ma sz\u00e1m\u00e1ra 21 bit van fenntartva a 32-b\u0151l \u2014 els\u0151 r\u00e1n\u00e9z\u00e9sre elegend\u0151 lenne a h\u00e1rom b\u00e1jt (amely \u00f6sszesen 24 bitet ad), de a seg\u00e9djel\u00f6l\u0151k t\u00fal sok helyet foglalnak el.<\/p>\n<p>Rossz ez? Val\u00f3j\u00e1ban nem annyira. Egyr\u00e9szt \u2014 ha nagyon \u00e9rdekel minket a helymegtakar\u00edt\u00e1s, vannak t\u00f6m\u00f6r\u00edt\u00e9si algoritmusaink, amelyek k\u00f6nnyed\u00e9n megsz\u00fcntetik az \u00f6sszes felesleges entr\u00f3pi\u00e1t \u00e9s redundanci\u00e1t. M\u00e1sr\u00e9szt \u2014 a Unicode c\u00e9lja a lehet\u0151 leguniverz\u00e1lisabb k\u00f3dol\u00e1s biztos\u00edt\u00e1sa volt. P\u00e9ld\u00e1ul, egy UTF-8-ban k\u00f3dolt sz\u00f6veget bizalommal adhatunk \u00e1t egy olyan k\u00f3dnak, amely kor\u00e1bban csak ASCII-val m\u0171k\u00f6d\u00f6tt, \u00e9s nem kell f\u00e9ln\u00fcnk, hogy olyan karaktert l\u00e1t, amely az ASCII tartom\u00e1ny\u00e1ban val\u00f3j\u00e1ban nincs jelen (mivel a UTF-8-ban minden b\u00e1jt, amely a nulladik bittel kezd\u0151dik \u2014 az pontosan ASCII). \u00c9s ha hirtelen el akarunk v\u00e1gni egy kis farok r\u00e9szt egy nagyobb sz\u00f6vegb\u0151l, an\u00e9lk\u00fcl, hogy az elej\u00e9t\u0151l dek\u00f3doln\u00e1nk (vagy helyre\u00e1ll\u00edtan\u00e1nk egy r\u00e9sz inform\u00e1ci\u00f3t a s\u00e9r\u00fclt r\u00e9szb\u0151l) \u2014 nem neh\u00e9z megtal\u00e1lni azt az eltol\u00e1st, ahol egy karakter kezd\u0151dik (el\u00e9g, ha kihagyjuk azokat a b\u00e1jtokat, amelyek bit prefixszel kezd\u0151dnek. <code><b>10<\/b><\/code>).<\/p>\n<h2>Mi\u00e9rt is kellene valami \u00fajat kital\u00e1lni?<\/h2>\n<p>\nUgyanakkor id\u0151nk\u00e9nt el\u0151fordulnak olyan helyzetek, amikor a deflate-hez hasonl\u00f3 t\u00f6m\u00f6r\u00edt\u00e9si algoritmusok rosszul alkalmazhat\u00f3k, de szeretn\u00e9nk a szavakat t\u00f6m\u00f6r\u00edtett form\u00e1ban t\u00e1rolni. Szem\u00e9ly szerint tal\u00e1lkoztam ezzel a feladattal, amikor a <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Radix_tree\">t\u00f6m\u00f6r\u00edtett prefixf\u00e1kr\u00f3l<\/a><\/noindex> \u00e9reztem, hogy egy nagy sz\u00f3t\u00e1rhoz, amely tetsz\u0151leges nyelv\u0171 szavakat tartalmaz. Egyr\u00e9szt minden sz\u00f3 nagyon r\u00f6vid, \u00edgy a t\u00f6m\u00f6r\u00edt\u00e9se nem lesz hat\u00e9kony. M\u00e1sr\u00e9szt az \u00e1ltalam vizsg\u00e1lt fa megval\u00f3s\u00edt\u00e1s\u00e1ra az volt jellemz\u0151, hogy a t\u00e1rolt sztring minden egyes byte-ja k\u00fcl\u00f6n cs\u00facsot gener\u00e1l, \u00edgy nagyon hasznos volt minimaliz\u00e1lni a sz\u00e1mukat. A k\u00f6nyvt\u00e1ramban <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/deNULL\/Az.js\">Az.js<\/a><\/noindex> (ahogyan a <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kmike\/pymorphy2\">pymorphy2<\/a><\/noindex>, amire \u00e9p\u00fcl) ilyen probl\u00e9ma egyszer\u0171en megold\u00f3dik - a <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Deterministic_acyclic_finite_state_automaton\">DAWG<\/a><\/noindex>-sz\u00f3t\u00e1rban t\u00e1rolt sztringek <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/deNULL\/Az.js\/blob\/master\/src\/az.dawg.js\">a r\u00e9gi sz\u00e9p CP1251-ben<\/a><\/noindex>. De, mint tudjuk, ez csak korl\u00e1tozott \u00e1b\u00e9c\u00e9 eset\u00e9n m\u0171k\u00f6dik j\u00f3l - egy k\u00ednai sz\u00f3t ilyen sz\u00f3t\u00e1rba m\u00e1r nem lehet beletenni.<\/p>\n<p>K\u00fcl\u00f6n megeml\u00edten\u00e9k m\u00e9g egy kellemetlen aspektust, amely a UTF-8 haszn\u00e1latakor mer\u00fcl fel ilyen adatstrukt\u00far\u00e1kban. A fenti k\u00e9pen l\u00e1that\u00f3, hogy amikor egy karaktert k\u00e9t byte-k\u00e9nt t\u00e1rolunk, a hozz\u00e1 tartoz\u00f3 bitek nem k\u00f6vetik egym\u00e1st, hanem fesz\u00fcltek egy p\u00e1r bit <code><b>10<\/b><\/code> a k\u00f6zep\u00e9n: <code><b>110xxxxx 10xxxxxx<\/b><\/code>. Emiatt, amikor a karakter k\u00f3dj\u00e1ban a m\u00e1sodik byte als\u00f3 6 bitjei t\u00falcsordulnak (azaz \u00e1tl\u00e9pik a <code><b>10111111<\/b><\/code> \u2192 <code><b>10000000<\/b><\/code>), akkor az els\u0151 byte is megv\u00e1ltozik. \u00cdgy a '\u043f' bet\u0171 byte-okkal van jel\u00f6lve <code><b>0xD0 0xBF<\/b><\/code>, m\u00edg ut\u00e1na a '\u0440' m\u00e1r <code><b>0xD1&nbsp;0x80<\/b><\/code>. A prefixfa eset\u00e9ben ez a sz\u00fcl\u0151cs\u00facs kett\u00e9v\u00e1l\u00e1s\u00e1hoz vezet - az egyik a prefix sz\u00e1m\u00e1ra, <code><b>0xD0<\/b><\/code>a m\u00e1sik pedig <code><b>0xD1<\/b><\/code> (b\u00e1r az \u00f6sszes cirill bet\u0171t csak a m\u00e1sodik byte-ban lehetne k\u00f3dolni).<\/p>\n<h2>Mit siker\u00fclt el\u00e9rnem<\/h2>\n<p>\nEzzel a feladattal tal\u00e1lkozva \u00fagy d\u00f6nt\u00f6ttem, hogy egy kicsit j\u00e1tszom a bitekkel, \u00e9s egy\u00fattal jobban megismerem a Unicode strukt\u00far\u00e1j\u00e1t \u00e1ltal\u00e1ban. Az eredm\u00e9ny egy UTF-C k\u00f3dol\u00e1si form\u00e1tum lett (a \u201eC\u201d a <em>t\u00f6m\u00f6r\u00edtett<\/em>), amely nem t\u00f6lt el t\u00f6bb mint 3 byte-ot egy k\u00f3dpontn\u00e1l, \u00e9s nagyon gyakran lehet\u0151v\u00e9 teszi, hogy az eg\u00e9sz k\u00f3dolt sztringhez csak <strong>egy plusz byte-ot haszn\u00e1ljunk<\/strong>. Ez oda vezet, hogy sok nem-ASCII \u00e1b\u00e9c\u00e9n ez a k\u00f3dol\u00e1s <strong>30-60%-kal t\u00f6m\u00f6rebb, mint a UTF-8<\/strong>.<\/p>\n<p>A k\u00f3dol\u00e1si \u00e9s dek\u00f3dol\u00e1si algoritmusok megval\u00f3s\u00edt\u00e1sa p\u00e9ld\u00e1kat \u00e1ll\u00edtottam <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/deNULL\/utf-c\">JavaScript \u00e9s Go nyelv\u0171 k\u00f6nyvt\u00e1rak form\u00e1j\u00e1ban.<\/a><\/noindex>, szabadon haszn\u00e1lhatja \u0151ket a k\u00f3dj\u00e1ban. De szeretn\u00e9m hangs\u00falyozni, hogy bizonyos \u00e9rtelemben ez a form\u00e1tum tov\u00e1bbra is <strong>an\u00e9lk\u00fcl, hogy tudn\u00e1nk, mire van sz\u00fcks\u00e9g\u00fcnk<\/strong>. Ez ink\u00e1bb k\u00eds\u00e9rlet, mint komoly<\/p>\n<p><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/e31978174449cd7de5d8371aaeb9ab2e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>az UTF-8 jav\u00edt\u00e1sa. Mindazon\u00e1ltal a k\u00f3d rendezett, t\u00f6m\u00f6r, sok komment\u00e1rral \u00e9s tesztel\u00e9ssel van ell\u00e1tva.<\/i><\/p>\n<p>Tov\u00e1bb\u00e1 k\u00e9sz\u00edtettem <noindex><a rel=\"nofollow\" href=\"https:\/\/denull.github.io\/utf-c\/\">egy bemutat\u00f3 oldalt<\/a><\/noindex>, ahol \u00e9rt\u00e9kelheti az algoritmus munk\u00e1j\u00e1t, \u00e9s ezek ut\u00e1n r\u00e9szletesebben besz\u00e9lek az elveir\u0151l \u00e9s a fejleszt\u00e9si folyamat\u00e1r\u00f3l.<\/p>\n<h2>T\u00falzott bitek elt\u00e1vol\u00edt\u00e1sa<\/h2>\n<p>\nAlapk\u00e9nt term\u00e9szetesen az UTF-8-at vettem. Az els\u0151 \u00e9s legnyilv\u00e1nval\u00f3bb dolog, amit meg lehet v\u00e1ltoztatni \u2014 cs\u00f6kkenteni a vez\u00e9rl\u0151 bitek sz\u00e1m\u00e1t minden b\u00e1jtban. P\u00e9ld\u00e1ul az els\u0151 b\u00e1jt az UTF-8-ban mindig azzal kezd\u0151dik, hogy <code><b>0<\/b><\/code>vagy a <code><b>11<\/b><\/code> \u2014 \u00e9s a prefix <code><b>10<\/b><\/code> csak a k\u00f6vetkez\u0151 b\u00e1jtokn\u00e1l tal\u00e1lhat\u00f3. Lecser\u00e9lj\u00fck a prefixet <code><b>11<\/b><\/code> Gyorsan eml\u00e9kezz\u00fcnk vissza, hogyan m\u0171k\u00f6dik a modul\u00e1ris aritmetika. Az \u00f3ra m\u00e1r egy ismert koncepci\u00f3. Az \u00f3r\u00e1k haszn\u00e1lata <code><b>1<\/b><\/code>, az al\u00e1bbi b\u00e1jtokn\u00e1l pedig teljesen elt\u00e1vol\u00edtjuk a prefixeket. Mi t\u00f6rt\u00e9nik?<\/p>\n<p><code><b>0xxxxxxx<\/b><\/code> \u2014 1 b\u00e1jt <br \/>\n<code><b>10xxxxxx xxxxxxxx<\/b><\/code> \u2014 2 b\u00e1jt <br \/>\n<code><b>110xxxxx xxxxxxxx xxxxxxxx<\/b><\/code> \u2014 3 b\u00e1jt<\/p>\n<p>V\u00e1rjunk, hol van a n\u00e9gy b\u00e1jtos el\u0151\u00edr\u00e1s? Az m\u00e1r nem sz\u00fcks\u00e9ges \u2014 h\u00e1rom b\u00e1jtn\u00e1l 21 bit el\u00e9rhet\u0151, \u00e9s ez b\u0151ven elegend\u0151 minden sz\u00e1mhoz, amely <code><b>0x10FFFF<\/b><\/code>.<\/p>\n<p>Mivel mondtunk le itt? A legfontosabb a karakterhat\u00e1rok \u00e9szlel\u00e9s\u00e9nek lehet\u0151s\u00e9ge b\u00e1rhol a pufferb\u0151l. Nem tudunk r\u00e1mutatni egy tetsz\u0151leges b\u00e1jt hely\u00e9re, hogy onnan megtal\u00e1ljuk a k\u00f6vetkez\u0151 karakter kezdet\u00e9t. Ez a form\u00e1tumunk korl\u00e1tja, de a gyakorlatban erre az ig\u00e9ny nem mer\u00fcl fel gyakran. \u00c1ltal\u00e1ban k\u00e9pesek vagyunk a puffert a legeslegelej\u00e9r\u0151l \u00e1tfutni (k\u00fcl\u00f6n\u00f6sen r\u00f6vid sorok eset\u00e9n).<\/p>\n<p>A 2 b\u00e1jtos nyelvek lefedetts\u00e9ge is javult: most a k\u00e9tr\u00e9szes form\u00e1tum 14 bit tartom\u00e1nyt ad, ami a k\u00f3dokig terjed <code><b>0x3FFF<\/b><\/code>. A k\u00ednaiaknak nem k\u00f6nny\u0171 (a hieroglif\u00e1ik f\u0151k\u00e9nt a tartom\u00e1nyban tal\u00e1lhat\u00f3k <code><b>0x4E00<\/b><\/code> t\u00f3l <code><b>0x9FFF<\/b><\/code>), de a gr\u00fazoknak \u00e9s sok m\u00e1s n\u00e9pnek sokkal sz\u00f3rakoztat\u00f3bb lett \u2014 a nyelveik is belef\u00e9rnek a 2 b\u00e1jtba karakterenk\u00e9nt.<\/p>\n<h2>Folytatjuk az enk\u00f3der \u00e1llapot\u00e1nak bevezet\u00e9s\u00e9t<\/h2>\n<p>\nMost gondoljunk a sorok tulajdons\u00e1gaira. A sz\u00f3t\u00e1rakban \u00e1ltal\u00e1ban olyan szavak tal\u00e1lhat\u00f3k, amelyek egy \u00e1b\u00e9c\u00e9 karaktereivel \u00edr\u00f3dtak, \u00e9s sok m\u00e1s sz\u00f6vegn\u00e9l is ez igaz. J\u00f3 lenne egyszer megadni ezt az \u00e1b\u00e9c\u00e9t, majd csak a bet\u0171 sz\u00e1m\u00e1t megadni benne. N\u00e9zz\u00fck meg, seg\u00edt-e nek\u00fcnk a karakterek elhelyezked\u00e9se a Unicode t\u00e1bl\u00e1ban.<\/p>\n<p>Ahogy fent eml\u00edtett\u00fck, a Unicode <em>s\u00edkokra van osztva<\/em> maximum of 65536 codes each. However, this division is not very useful (as mentioned, we are mostly in the zero plane). A more interesting division is into <em>blocks.<\/em> These ranges no longer have fixed lengths and carry more meaning \u2014 as a rule, each unites characters of the same alphabet.<\/p>\n<p><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/61ea5e859d7e6d9c75e977a3579ff28f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>A block containing characters from the Bengali alphabet. Unfortunately, due to historical reasons, this is an example of not very dense packing \u2014 96 characters are randomly scattered across 128 code points of the block.<\/i><\/p>\n<p>The starting points of the blocks and their sizes are always multiples of 16 \u2014 this is simply done for convenience. In addition, many blocks start and end at values that are multiples of 128 or even 256 \u2014 for example, the main Cyrillic occupies 256 bytes from <code><b>0x0400<\/b><\/code> t\u00f3l <code><b>0x04FF<\/b><\/code>. This is quite convenient: if we save the prefix once <code><b>0x04<\/b><\/code>, then any Cyrillic character can be recorded in one byte. However, this way we lose the ability to return to ASCII (and to any other characters at all). Therefore, we do it like this:<\/p>\n<ol>\n<li>Two bytes <code><b>10yyyyyy yxxxxxxx<\/b><\/code> not only denote the character with the number <code><b>yyyyyy yxxxxxxx<\/b><\/code>, but also change <em>the current alphabet<\/em> Gyorsan eml\u00e9kezz\u00fcnk vissza, hogyan m\u0171k\u00f6dik a modul\u00e1ris aritmetika. Az \u00f3ra m\u00e1r egy ismert koncepci\u00f3. Az \u00f3r\u00e1k haszn\u00e1lata <code><b>yyyyyy y0000000<\/b><\/code> (i.e., we remember all bits except the least significant <strong>7 bits<\/strong>);<\/li>\n<li>One byte <code><b>0xxxxxxx<\/b><\/code> is a symbol from the current alphabet. It just needs to be added to the offset we remembered in step 1. As long as we haven't changed the alphabet, the offset is zero, so we maintained compatibility with ASCII.<\/li>\n<\/ol>\n<p>\nSimilarly for codes requiring 3 bytes:<\/p>\n<ol>\n<li>Three bytes <code><b>110yyyyy yxxxxxxx xxxxxxxx<\/b><\/code> denote the character with the number <code><b>yyyyyy yxxxxxxx xxxxxxxx<\/b><\/code>, change <em>the current alphabet<\/em> Gyorsan eml\u00e9kezz\u00fcnk vissza, hogyan m\u0171k\u00f6dik a modul\u00e1ris aritmetika. Az \u00f3ra m\u00e1r egy ismert koncepci\u00f3. Az \u00f3r\u00e1k haszn\u00e1lata <code><b>yyyyyy y0000000 00000000<\/b><\/code> (we remembered everything except the least significant <strong>15 bits<\/strong>), and set a flag that we are now in <em>long<\/em> mode (when switching the alphabet back to two-byte, we will reset this flag);<\/li>\n<li>Two bytes <code><b>0xxxxxxx xxxxxxxx<\/b><\/code> in long mode this is a symbol from the current alphabet. Similarly, we add it to the offset from step 1. The only difference is that now we read two bytes (because we switched to this mode).<\/li>\n<\/ol>\n<p>\nSounds good: now as long as we need to encode characters from the same 7-bit Unicode range, we spend 1 extra byte at the start and only 1 byte for each character.<\/p>\n<p><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/084d636a25dccdaa9f5a6eb5233c8e99.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>The work of one of the early versions. It already often surpasses UTF-8, but there is still room for improvement.<\/i><\/p>\n<p>What has gotten worse? Firstly, we have a state, namely <em>the offset of the current alphabet<\/em> and the flag <em>of long mode<\/em>Ez kieg\u00e9sz\u00edt\u0151leg korl\u00e1toz minket: most m\u00e1r ugyanazok a karakterek k\u00fcl\u00f6nb\u00f6z\u0151 kontextusokban elt\u00e9r\u0151en k\u00f3dolhat\u00f3k. P\u00e9ld\u00e1ul a r\u00e9szstringek keres\u00e9se m\u00e1r figyelembe kell, hogy vegye ezt, nem csak a byte-ok \u00f6sszehasonl\u00edt\u00e1sa alapj\u00e1n. M\u00e1sodsorban, amint megv\u00e1ltoztattuk az \u00e1b\u00e9c\u00e9t, az ASCII karakterek k\u00f3dol\u00e1sa probl\u00e9m\u00e1ss\u00e1 v\u00e1lt (ez nemcsak a latin \u00edr\u00e1s, hanem az alapvet\u0151 \u00edr\u00e1sjeleket is, bele\u00e9rtve a sz\u00f3k\u00f6z\u00f6ket) \u2014 ezek ism\u00e9telt \u00e1b\u00e9cs-v\u00e1lt\u00e1st ig\u00e9nyelnek 0-ra, teh\u00e1t \u00fajabb felesleges byte-ra (azt\u00e1n egy \u00fajabb arra, hogy visszat\u00e9rj\u00fcnk az alapunkhoz).<\/p>\n<h2>Egy \u00e1b\u00e9c\u00e9 j\u00f3, kett\u0151 \u2014 jobb<\/h2>\n<p>\nPr\u00f3b\u00e1ljunk kicsit v\u00e1ltoztatni a bitek el\u0151tagjain: hozz\u00e1adunk egyet a h\u00e1rom el\u0151z\u0151leg eml\u00edtetthez:<\/p>\n<p><code><b>0xxxxxxx<\/b><\/code> \u2014 1 byte norm\u00e1l m\u00f3dban, 2 hossz\u00fa m\u00f3dban <br \/>\n<code><b>11xxxxxx<\/b><\/code> \u2014 1 b\u00e1jt <br \/>\n<code><b>100xxxxx xxxxxxxx<\/b><\/code> \u2014 2 b\u00e1jt <br \/>\n<code><b>101xxxxx xxxxxxxx xxxxxxxx<\/b><\/code> \u2014 3 b\u00e1jt<\/p>\n<p><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/fa1eca1adb80b15a4cf4f60f57a09c6c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMost k\u00e9tbyte-os k\u00f3dol\u00e1sban egy el\u00e9rhet\u0151 bittel kevesebb lett \u2014 a k\u00f3dpontok eg\u00e9szen addig f\u00e9rnek el <code><b>0x1FFF<\/b><\/code>, nem pedig <code><b>0x3FFF<\/b><\/code>. Azonban m\u00e9g mindig \u00e9rz\u00e9kelhet\u0151en t\u00f6bb, mint a k\u00e9tbyte-os UTF-8 k\u00f3dokban, a legt\u00f6bb elterjedt nyelv m\u00e9g mindig belef\u00e9r, a legszembet\u0171n\u0151bb vesztes\u00e9g \u2014 kiesett <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A5%D0%B8%D1%80%D0%B0%D0%B3%D0%B0%D0%BD%D0%B0\">hiragana<\/a><\/noindex> \u00e9s <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9A%D0%B0%D1%82%D0%B0%D0%BA%D0%B0%D0%BD%D0%B0\">katakana<\/a><\/noindex>, a jap\u00e1nok szomor\u00faak.<\/p>\n<p>Mi ez az \u00faj k\u00f3d <code><b>11xxxxxx<\/b><\/code>? \u042d\u0442\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u00ab\u0437\u0430\u0433\u0430\u0448\u043d\u0438\u043a\u00bb \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0432 64 \u0441\u0438\u043c\u0432\u043e\u043b\u0430, \u043e\u043d \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0430\u0448 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0430\u043b\u0444\u0430\u0432\u0438\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043d\u0430\u0437\u0432\u0430\u043b \u0435\u0433\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c (<em>auxiliary<\/em>) \u00e1b\u00e9c\u00e9. Amikor v\u00e1ltunk a jelenlegi \u00e1b\u00e9c\u00e9r\u0151l, a r\u00e9gi \u00e1b\u00e9c\u00e9 egy r\u00e9sze seg\u00e9d\u00e1b\u00e9cs\u00e9 v\u00e1lik. P\u00e9ld\u00e1ul, ha ASCII-r\u00f3l cirillre v\u00e1ltunk \u2014 a \u201et\u00e1rol\u00f3ban\u201d most 64 karakter van, amelyek tartalmazz\u00e1k <strong>a latin bet\u0171ket, sz\u00e1mokat, sz\u00f3k\u00f6zt \u00e9s vessz\u0151t<\/strong> (a leggyakoribb besz\u00far\u00e1sok nem-ASCII sz\u00f6vegekben). Visszav\u00e1ltva ASCII-ra \u2014 a seg\u00e9d\u00e1b\u00e9cs\u00e9 a cirill f\u0151 r\u00e9sze v\u00e1lik.<\/p>\n<p>K\u00e9t \u00e1b\u00e9c\u00e9hez val\u00f3 hozz\u00e1f\u00e9r\u00e9ssel t\u00f6bbf\u00e9le sz\u00f6veggel elboldogulhatunk, minim\u00e1lis \u00fczemeltet\u00e9si k\u00f6lts\u00e9gekkel az \u00e1b\u00e9csv\u00e1lt\u00e1sn\u00e1l (a sz\u00f3foglal\u00e1s gyakran visszavezet az ASCII-ra, de ezt k\u00f6vet\u0151en sok nem-ASCII karaktert m\u00e1r a seg\u00e9d\u00e1b\u00e9cs\u00e9b\u0151l k\u00e9pesek lesz\u00fcnk kinyerni, an\u00e9lk\u00fcl, hogy \u00fajb\u00f3l v\u00e1ltan\u00e1nk).<\/p>\n<p>B\u00f3nusz: a seg\u00e9d\u00e1b\u00e9cs\u00e9 megjel\u00f6l\u00e9s\u00e9vel el\u0151taggal <code><b>11xxxxxx<\/b><\/code> \u00e9s az inicializ\u00e1l\u00f3 eltol\u00e1s\u00e1nak be\u00e1ll\u00edt\u00e1s\u00e1val <code><b>0xC0<\/b><\/code>, r\u00e9szleges kompatibilit\u00e1st kapunk a CP1252-vel. M\u00e1s sz\u00f3val, sok (de nem minden) nyugat-eur\u00f3pai sz\u00f6veg, amely CP1252-ben van k\u00f3dolva, ugyan\u00fagy fog kin\u00e9zni UTF-C-ben.<\/p>\n<p>Itt viszont felmer\u00fcl egy neh\u00e9zs\u00e9g: hogyan lehet a f\u0151 \u00e1b\u00e9c\u00e9b\u0151l seg\u00e9d\u00e1b\u00e9c\u00e9t l\u00e9trehozni? A pontos eltol\u00e1st meghagyhatjuk, de \u2014 sajnos\u2014 itt a Unicode szerkezete m\u00e1r ellen\u00fcnkre j\u00e1tszik. Nagyon gyakran a f\u0151 \u00e1b\u00e9c\u00e9 r\u00e9sze nem a blokk elej\u00e9n tal\u00e1lhat\u00f3 (p\u00e9ld\u00e1ul az orosz nagybet\u0171s \u201eA\u201d k\u00f3dja) <code>0x04<b>10<\/b><\/code>, b\u00e1r a cirill blokk a <code>0x04<b>00<\/b><\/code>). \u00cdgy ha az els\u0151 64 karaktert a \u201etartal\u00e9kba\u201d vessz\u00fck, lehet, hogy elvesz\u00edtj\u00fck a bet\u0171rend h\u00e1ts\u00f3 r\u00e9sz\u00e9hez val\u00f3 hozz\u00e1f\u00e9r\u00e9st.<\/p>\n<p>A probl\u00e9ma megold\u00e1s\u00e1hoz manu\u00e1lisan v\u00e9gigmentem n\u00e9h\u00e1ny blokkra, amelyek k\u00fcl\u00f6nb\u00f6z\u0151 nyelvekhez tartoznak, \u00e9s megadtam sz\u00e1mukra a seg\u00e9d\u00e1bcshiftet a f\u0151ben. A latin bet\u0171sort, kiv\u00e9telk\u00e9nt, teljesen \u00fajrarendeztem, mint a base64.<\/p>\n<p><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/d191a3bb17403e99d506dbd008b63159.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h2>Befejez\u00e9si sim\u00edt\u00e1sok<\/h2>\n<p>\nN\u00e9zz\u00fck meg v\u00e9g\u00fcl, hol tudunk m\u00e9g valamin jav\u00edtani.<\/p>\n<p>\u00c9szrevessz\u00fck, hogy a form\u00e1tum <code><b>101xxxxx xxxxxxxx xxxxxxxx<\/b><\/code> lehet\u0151v\u00e9 teszi a sz\u00e1mok k\u00f3dol\u00e1s\u00e1t eg\u00e9szen <code><b>0x1FFFFF<\/b><\/code>, m\u00edg a Unicode hamarabb v\u00e9get \u00e9r, n\u00e1lunk pedig <code><b>0x10FFFF<\/b><\/code>. M\u00e1s sz\u00f3val, az utols\u00f3 k\u00f3dpontot \u00edgy fogjuk megjelen\u00edteni, mint <code><b>10110000 11111111 11111111<\/b><\/code>. \u00cdgy mondhatjuk, hogy ha az els\u0151 b\u00e1jt a k\u00f6vetkez\u0151k\u00e9ppen n\u00e9z ki <code><b>1011xxxx<\/b><\/code> (ahol \u2014 hexadecim\u00e1lis sz\u00e1mjegy). Ez a hexadecim\u00e1lis \u00e1br\u00e1zol\u00e1s a Unicode k\u00f3dpontjaira a <code><b>xxxx<\/b><\/code> nagyobb 0), akkor valami m\u00e1st jelent. P\u00e9ld\u00e1ul m\u00e9g 15 karaktert is hozz\u00e1adhatunk, amelyek folyamatosan k\u00f3dolhat\u00f3k egy b\u00e1jton, de \u00e9n m\u00e1sk\u00e9pp d\u00f6nt\u00f6ttem.<\/p>\n<p>N\u00e9zz\u00fck a Unicode azon blokkjait, amelyek jelenleg h\u00e1rom b\u00e1jtot ig\u00e9nyelnek. F\u0151leg, mint m\u00e1r eml\u00edtett\u00fck, ezek k\u00ednai karakterek \u2014 de vel\u00fck neh\u00e9z b\u00e1rmit is kezdeni, hiszen 21 ezer van bel\u0151l\u00fck. De a hiragana \u00e9s katakana is elment od\u00e1ig \u2014 bel\u0151l\u00fck m\u00e1r nem sok van, kevesebb mint k\u00e9tsz\u00e1z. \u00c9s ha m\u00e1r eml\u00edtj\u00fck a jap\u00e1nokat \u2014 itt tal\u00e1lhat\u00f3k az emoji-k is (val\u00f3j\u00e1ban sok helyen sz\u00e9tsz\u00f3rva a Unicode-ban, de az alap blokkok a tartom\u00e1nyban <code><b>0x1F300<\/b><\/code> \u2013 <code><b>0x1FBFF<\/b><\/code>). Ha arra gondolunk, hogy jelenleg l\u00e9teznek olyan emoji-k, amelyek azonnal t\u00f6bb k\u00f3dpontb\u00f3l \u00e1llnak \u00f6ssze (p\u00e9ld\u00e1ul az emoji \u200d\u200d\u200d<noindex><a rel=\"nofollow\" href=\"https:\/\/emojipedia.org\/family-woman-woman-girl-boy\/\"><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/76cd12423b241cc316af80f03be4348f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex> \u00f6sszesen 7 k\u00f3db\u00f3l \u00e1ll!), akkor t\u00e9nyleg szomor\u00fa, hogy mindegyikre h\u00e1rom b\u00e1jtot pazaroljunk (7\u00d73 = 21 b\u00e1jt egy karakter\u00e9rt, r\u00e9m\u00e1lom).<\/p>\n<p>Ez\u00e9rt v\u00e1lasztunk ki n\u00e9h\u00e1ny kiv\u00e1lasztott tartom\u00e1nyt, amelyek az emoji-k, a hiragana \u00e9s katakana sz\u00e1m\u00e1ra vonatkoznak, \u00fajrasz\u00e1mozzuk \u0151ket egy folytonos list\u00e1ban \u00e9s k\u00f3doljuk \u0151ket k\u00e9t b\u00e1jtk\u00e9nt a h\u00e1rom helyett:<\/p>\n<p><code><b>1011xxxx xxxxxxxx<\/b><\/code> <\/p>\n<p>J\u00f3: a fent eml\u00edtett emoji \u200d\u200d\u200d<noindex><a rel=\"nofollow\" href=\"https:\/\/emojipedia.org\/family-woman-woman-girl-boy\/\"><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/b9900c78dda5d8e596e3751021b4d35d.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex>7 k\u00f3dpontb\u00f3l \u00e1ll, az UTF-8-ban 25 b\u00e1jt, m\u00edg mi k\u00e9t b\u00e1jtra s\u0171r\u00edtett\u00fck \u0151t <strong>14<\/strong> ( pontosan k\u00e9t b\u00e1jt minden k\u00f3dpontra). Egy\u00e9bk\u00e9nt a Habr nem volt hajland\u00f3 feldolgozni (sem a r\u00e9gi, sem az \u00faj szerkeszt\u0151ben), ez\u00e9rt k\u00e9p form\u00e1j\u00e1ban kellett beilleszteni.<\/p>\n<p>Pr\u00f3b\u00e1ljuk meg jav\u00edtani egy m\u00e1sik probl\u00e9m\u00e1t is. Amint eml\u00e9ksz\u00fcnk, a f\u0151 \u00e1b\u00e9c\u00e9 l\u00e9nyeg\u00e9ben <strong>a legmagasabb 6 bit<\/strong>, amelyeket \u00e9szben tartunk, \u00e9s minden egyes dek\u00f3dolt karakterhez hozz\u00e1rendel\u00fcnk a k\u00f3d sor\u00e1n. A k\u00ednai \u00edr\u00e1sjegyek eset\u00e9n, amelyek egy blokkban tal\u00e1lhat\u00f3k, <code><b>0x4E00<\/b><\/code> \u2013 <code><b>0x9FFF<\/b><\/code>, ez vagy 0, vagy 1. Ez nem t\u00fal k\u00e9nyelmes: folyamatosan v\u00e1ltanunk kell az \u00e1b\u00e9c\u00e9t e k\u00e9t \u00e9rt\u00e9k k\u00f6z\u00f6tt (azaz h\u00e1rom byte-ot kell haszn\u00e1lnunk). De vegy\u00fck \u00e9szre, hogy hossz\u00fa \u00fczemm\u00f3dban a k\u00f3db\u00f3l le tudjuk vonni a karakterek sz\u00e1m\u00e1t, amelyet a r\u00f6vid \u00fczemm\u00f3dban k\u00f3doltunk (ez 10240, miut\u00e1n a fent eml\u00edtett tr\u00fckk\u00f6ket alkalmaztuk) \u2014 \u00edgy a \u00edr\u00e1sjegyek tartom\u00e1nya eltol\u00f3dik <code><b>0x2600<\/b><\/code> \u2013 <code><b>0x77FF<\/b><\/code>, \u00e9s ebben az esetben az eg\u00e9sz tartom\u00e1nyban a legfels\u0151 6 bit (21-b\u0151l) 0 lesz. \u00cdgy az \u00edr\u00e1sjegy-sorozatok minden \u00edr\u00e1sjegyhez k\u00e9t byte-ot haszn\u00e1lnak (ami optim\u00e1lis egy ekkora tartom\u00e1nyhoz), elker\u00fclve az \u00e1b\u00e9c\u00e9 v\u00e1lt\u00e1sait. <\/p>\n<h2>Alternat\u00edv megold\u00e1sok: SCSU, BOCU-1<\/h2>\n<p>\nA Unicode szakemberei, miut\u00e1n elolvast\u00e1k a cikk c\u00edm\u00e9t, val\u00f3sz\u00edn\u0171leg sietve eml\u00e9keztetni fogj\u00e1k, hogy a Unicode szabv\u00e1nyai k\u00f6z\u00f6tt <noindex><a rel=\"nofollow\" href=\"https:\/\/www.unicode.org\/reports\/tr6\/tr6-4.html\">Standard Compression Scheme for Unicode<\/a><\/noindex> (SCSU), amely egy nagyon hasonl\u00f3 k\u00f3dol\u00e1si m\u00f3dot \u00edr le, mint amit a cikkben bemutatnak.<\/p>\n<p>Bevallom \u0151szint\u00e9n: a l\u00e9tez\u00e9s\u00e9r\u0151l csak m\u00e9lyebben a saj\u00e1t megold\u00e1som kidolgoz\u00e1s\u00e1ba mer\u00fclve \u00e9rtes\u00fcltem. Ha tudtam volna r\u00f3la az elej\u00e9t\u0151l fogva, val\u00f3sz\u00edn\u0171leg megpr\u00f3b\u00e1ltam volna a megval\u00f3s\u00edt\u00e1s\u00e1t \u00edrni a saj\u00e1t megk\u00f6zel\u00edt\u00e9sem helyett.<\/p>\n<p>Ami \u00e9rdekes, hogy az SCSU olyan \u00f6tleteket haszn\u00e1l, amelyek nagyon hasonl\u00edtanak azokra, amelyeket \u00e9n magam is eljutottam (az \u00bb\u00e1b\u00e9c\u00e9k\u00ab fogalma helyett \u00bbablakokat\u00ab haszn\u00e1lnak, \u00e9s ezekb\u0151l t\u00f6bb is el\u00e9rhet\u0151, mint n\u00e1lam). Ugyanakkor ennek a form\u00e1tumnak is vannak h\u00e1tr\u00e1nyai: egy kicsit k\u00f6zelebb \u00e1ll a t\u00f6m\u00f6r\u00edt\u00e9si algoritmusokhoz, mint a k\u00f3dol\u00e1shoz. K\u00fcl\u00f6n\u00f6sen a szabv\u00e1ny sz\u00e1mos reprezent\u00e1ci\u00f3s m\u00f3dot ad, de nem mondja el, hogyan v\u00e1laszd ki a legjobbat \u2014 ehhez az encodernek valamilyen heuristik\u00e1t kell alkalmaznia. \u00cdgy az SCSU-encoder, amely j\u00f3 csomagol\u00e1st ad, bonyolultabb \u00e9s terjedelmesebb lesz, mint az \u00e9n algoritmusom.<\/p>\n<p>\u00d6sszehasonl\u00edt\u00e1s v\u00e9gett egy viszonylag egyszer\u0171 SCSU-implement\u00e1ci\u00f3t vittem \u00e1t JavaScriptbe \u2014 a k\u00f3d mennyis\u00e9ge \u00f6sszehasonl\u00edthat\u00f3 volt az \u00e9n UTF-C-mmel, de bizonyos esetekben t\u00edzsz\u00e1zal\u00e9kosan rosszabb eredm\u00e9nyt mutatott (n\u00e9ha ak\u00e1r meghaladja is, de nem sokkal). P\u00e9ld\u00e1ul h\u00e9ber \u00e9s g\u00f6r\u00f6g sz\u00f6vegekn\u00e9l az UTF-C-t 60%-kal jobban k\u00f3dolta, mint az SCSU <strong>(val\u00f3sz\u00edn\u0171leg az \u0151 kompakt \u00e1b\u00e9c\u00e9ik miatt).<\/strong> (val\u00f3sz\u00edn\u0171leg a kompakt \u00e1b\u00e9c\u00e9ik miatt).<\/p>\n<p>Meg kell eml\u00edtenem, hogy az SCSU mellett l\u00e9tezik egy m\u00e1sik, a Unicode t\u00f6m\u00f6r\u00edtett reprezent\u00e1l\u00e1s\u00e1ra szolg\u00e1l\u00f3 m\u00f3dszer \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Binary_Ordered_Compression_for_Unicode\">BOCU-1<\/a><\/noindex>, de ennek c\u00e9lja a MIME kompatibilit\u00e1s (amire nekem nem volt sz\u00fcks\u00e9gem), \u00e9s a k\u00f3dol\u00e1sra m\u00e1s megk\u00f6zel\u00edt\u00e9st alkalmaz. Az hat\u00e1sfok\u00e1t nem \u00e9rt\u00e9keltem, de \u00fagy gondolom, hogy val\u00f3sz\u00edn\u0171leg nem lesz magasabb, mint az SCSU-\u00e9.<\/p>\n<h2>Lehets\u00e9ges fejleszt\u00e9sek<\/h2>\n<p>\nAz \u00e1ltalam bemutatott algoritmus nem univerz\u00e1lis tervez\u00e9s alapj\u00e1n (ebben tal\u00e1n a c\u00e9ljaim a legink\u00e1bb elt\u00e9rnek a Unicode konzorcium c\u00e9ljait\u00f3l). M\u00e1r eml\u00edtettem, hogy els\u0151sorban egy feladatra (t\u00f6bbnyelv\u0171 sz\u00f3t\u00e1r prefixel el\u00e1gaz\u00f3 f\u00e1ban t\u00f6rt\u00e9n\u0151 t\u00e1rol\u00e1s\u00e1ra) fejlesztett\u00e9k ki, \u00e9s bizonyos jellemz\u0151i nem felt\u00e9tlen\u00fcl alkalmasak m\u00e1s feladatokra. De az a t\u00e9ny, hogy nem standard, ak\u00e1r el\u0151ny is lehet \u2014 <strong>k\u00f6nnyen testreszabhatja az ig\u00e9nyeihez<\/strong>.<\/p>\n<p>P\u00e9ld\u00e1ul nyilv\u00e1nval\u00f3an megszabadulhat a \u00e1llapott\u00f3l, stateless k\u00f3dol\u00e1st v\u00e9gezve \u2014 egyszer\u0171en nem friss\u00edtve a v\u00e1ltoz\u00f3kat <code><b>lev\u00e9l<\/b><\/code>, <code><b>auxOffs<\/b><\/code> \u00e9s <code><b>is21Bit<\/b><\/code> a k\u00f3dol\u00f3ban \u00e9s dek\u00f3dol\u00f3ban. Ebben az esetben nem lehet hat\u00e9konyan csomagolni egy \u00e1b\u00e9c\u00e9 karaktereinek sorozatait, viszont biztos\u00edtva van, hogy ugyanaz a karakter mindig ugyanazokkal a b\u00e1jtokkal van k\u00f3dolva, f\u00fcggetlen\u00fcl a kontextust\u00f3l.<\/p>\n<p>Ezen k\u00edv\u00fcl, a k\u00f3dol\u00f3t egy adott nyelvhez is csiszolhatjuk, megv\u00e1ltoztatva az alap\u00e9rtelmezett \u00e1llapotot \u2014 p\u00e9ld\u00e1ul orosz sz\u00f6vegek eset\u00e9n be\u00e1ll\u00edthatja a k\u00f3dol\u00f3 \u00e9s dek\u00f3dol\u00f3 elej\u00e9n. <code><b>offs = 0x0400<\/b><\/code> \u00e9s <code><b>auxOffs = 0<\/b><\/code>. K\u00fcl\u00f6n\u00f6sen \u00e9rdemes figyelembe venni ezt stateless m\u00f3dban. \u00d6sszess\u00e9g\u00e9ben ez hasonl\u00f3 lesz a r\u00e9gi nyolcbites k\u00f3dol\u00e1s haszn\u00e1lat\u00e1hoz, csak nem z\u00e1rja ki a Unicode \u00f6sszes karakter\u00e9nek sz\u00fcks\u00e9g szerinti besz\u00far\u00e1s\u00e1t.<\/p>\n<p>Egy m\u00e1sik kor\u00e1bban eml\u00edtett h\u00e1tr\u00e1ny \u2014 a UTF-C-ben k\u00f3dolt nagy mennyis\u00e9g\u0171 sz\u00f6veg eset\u00e9ben nincs gyors m\u00f3d a legk\u00f6zelebbi karakter hat\u00e1r\u00e1nak megtal\u00e1l\u00e1s\u00e1ra egy tetsz\u0151leges b\u00e1jthoz. Ha lev\u00e1g a k\u00f3dolt pufferb\u0151l mondjuk az utols\u00f3 100 b\u00e1jtot, akkor vesz\u00e9lybe sodorhatja mag\u00e1t, hogy hullad\u00e9kot kap, amivel semmit sem tud kezdeni. A t\u00f6bb gigab\u00e1jtos napl\u00f3k t\u00e1rol\u00e1s\u00e1ra a k\u00f3dol\u00e1s nem lett kifejlesztve, de \u00e1ltal\u00e1ban ezt lehet jav\u00edtani. A b\u00e1jt <code><b>0xBF<\/b><\/code> soha nem lehet az els\u0151 b\u00e1jt, de lehet m\u00e1sodik vagy harmadik. Teh\u00e1t k\u00f3dol\u00e1s sor\u00e1n be lehet illeszteni a sorozatot <code><b>0xBF 0xBF 0xBF<\/b><\/code> mondjuk, 10 Kb-k\u00e9nt \u2014 ebben az esetben elegend\u0151 a v\u00e1lasztott r\u00e9szletet \u00e1tvizsg\u00e1lni, am\u00edg meg nem tal\u00e1ljuk a megfelel\u0151 jel\u00f6l\u0151t. A legutols\u00f3 ut\u00e1n <code><b>0xBF<\/b><\/code> garant\u00e1ltan a karakter kezdete lesz. (Dek\u00f3dol\u00e1skor ezt a h\u00e1rom b\u00e1jtot figyelmen k\u00edv\u00fcl kell hagyni.)<\/p>\n<h2>\u00d6sszefoglalva<\/h2>\n<p>\nHa eddig eljutott\u00e1l \u2014 gratul\u00e1lok! Rem\u00e9lem, te is, ak\u00e1rcsak \u00e9n, tanult\u00e1l valami \u00fajat (vagy felid\u00e9zted a r\u00e9git) a Unicode rendszer\u00e9r\u0151l.<\/p>\n<p><img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/f14b2d815b06a7fda7b77c0a32e7eb75.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Demonstr\u00e1ci\u00f3s oldal. A h\u00e9ber p\u00e9ld\u00e1j\u00e1n l\u00e1that\u00f3ak az UTF-8 \u00e9s SCSU el\u0151nyei is.<\/i><\/p>\n<p>Ne tekintsd a fent le\u00edrt kutat\u00e1st a standardok megs\u00e9rt\u00e9s\u00e9nek. \u00c9n azonban \u00f6sszess\u00e9g\u00e9ben el\u00e9gedett vagyok az eredm\u00e9nyeimmel, ez\u00e9rt \u00f6r\u00f6mmel <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/deNULL\/utf-c\">osztom meg<\/a><\/noindex>: p\u00e9ld\u00e1ul a JS k\u00f6nyvt\u00e1r t\u00f6m\u00f6r\u00edtett form\u00e1ban mind\u00f6ssze 1710 b\u00e1jt s\u00faly\u00fa (\u00e9s term\u00e9szetesen nincs f\u00fcgg\u0151s\u00e9ge). Ahogy m\u00e1r eml\u00edtettem, a m\u0171k\u00f6d\u00e9s\u00e9vel megismerkedhetsz a <noindex><a rel=\"nofollow\" href=\"https:\/\/denull.github.io\/utf-c\/\">bemutat\u00f3 oldalon<\/a><\/noindex> (ott sz\u00f6vegek is tal\u00e1lhat\u00f3k, amelyek alapj\u00e1n \u00f6sszehasonl\u00edthatod az UTF-8-cal \u00e9s SCSU-val).<\/p>\n<p>V\u00e9gezet\u00fcl m\u00e9g egyszer felh\u00edvom a figyelmet az UTF-C haszn\u00e1lat\u00e1nak eseteire. <b>nem \u00e9rdemes<\/b>:<\/p>\n<ul>\n<li>Ha a soraid el\u00e9g hossz\u00faak (100-200 karaktert\u0151l). Ebben az esetben \u00e9rdemes megfontolni a t\u00f6m\u00f6r\u00edt\u00e9si algoritmusok, p\u00e9ld\u00e1ul a deflate alkalmaz\u00e1s\u00e1t.<\/li>\n<li>Ha sz\u00fcks\u00e9ged van <em>ASCII \u00e1tj\u00e1rhat\u00f3s\u00e1gra<\/em>, azaz fontos sz\u00e1modra, hogy a k\u00f3dolt szekvenci\u00e1kban ne jelenjenek meg olyan ASCII k\u00f3dok, amelyek nem voltak az eredeti sorban. Ezt a sz\u00fcks\u00e9gletet elker\u00fclheted, ha harmadik f\u00e9lt\u0151l sz\u00e1rmaz\u00f3 API-kkal (p\u00e9ld\u00e1ul adatb\u00e1zisokkal dolgozva) az eredm\u00e9ny k\u00f3dol\u00e1s\u00e1t absztrakt b\u00e1jt halmazk\u00e9nt adod \u00e1t, nem pedig karakterl\u00e1nck\u00e9nt. Ellenkez\u0151 esetben el\u0151re nem l\u00e1that\u00f3 sebezhet\u0151s\u00e9gek mer\u00fclhetnek fel.<\/li>\n<li>Ha gyorsan szeretn\u00e9d megtal\u00e1lni a karakterek hat\u00e1rait tetsz\u0151leges eltol\u00e1s szerint (p\u00e9ld\u00e1ul egy sor r\u00e9sz\u00e9nek megs\u00e9r\u00fcl\u00e9se eset\u00e9n). Ezt meg lehet tenni, de csak a sor elej\u00e9t\u0151l t\u00f6rt\u00e9n\u0151 \u00e1tvizsg\u00e1l\u00e1s \u00fatj\u00e1n (vagy a kor\u00e1bban eml\u00edtett kieg\u00e9sz\u00edt\u00e9s alkalmaz\u00e1s\u00e1val).<\/li>\n<li>Ha sz\u00fcks\u00e9ged van gyors m\u0171veletek v\u00e9grehajt\u00e1s\u00e1ra a karakterl\u00e1ncok tartalm\u00e1val (sorol\u00e1s, r\u00e9szstringek keres\u00e9se, \u00f6sszef\u0171z\u00e9s). Ehhez a karakterl\u00e1ncokat el\u0151sz\u00f6r dek\u00f3dolni kell, ez\u00e9rt az UTF-C lassabb lesz az UTF-8-n\u00e1l ezekben az esetekben (de gyorsabb a t\u00f6m\u00f6r\u00edt\u0151 algoritmusokn\u00e1l). Mivel ugyanaz a karakterl\u00e1nc mindig ugyan\u00fagy k\u00f3dol\u00f3dik, a pontos dek\u00f3dol\u00e1s \u00f6sszehasonl\u00edt\u00e1sa nem ig\u00e9nyel, byte-onk\u00e9nt v\u00e9gezhet\u0151.<\/li>\n<\/ul>\n<p><b>Friss\u00edt\u00e9s:<\/b> a felhaszn\u00e1l\u00f3 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/tyomitch\/\"><b>tyomitch<\/b><\/a><\/noindex> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/521110\/#comment_22139258\">a megjegyz\u00e9sekben<\/a><\/noindex> k\u00f6zz\u00e9tettem egy \u00e1br\u00e1t, amely kiemeli az UTF-C alkalmazhat\u00f3s\u00e1gi hat\u00e1rait. Ezen l\u00e1that\u00f3, hogy az UTF-C hat\u00e9konyabb, mint a \u00e1ltal\u00e1nos c\u00e9l\u00fa t\u00f6m\u00f6r\u00edt\u00e9si algoritmus (LZW v\u00e1ltozatai), am\u00edg a t\u00f6m\u00f6r\u00edtend\u0151 sz\u00f6veg r\u00f6videbb <b>~140 karakter<\/b> (igaz, megjegyzem, hogy az \u00f6sszehasonl\u00edt\u00e1st egyetlen sz\u00f6vegen v\u00e9gezt\u00fck; m\u00e1s nyelvekn\u00e9l az eredm\u00e9ny elt\u00e9rhet).<br \/>\n<img decoding=\"async\" alt=\"M\u00e9g egy ker\u00e9k: a Unicode karakterl\u00e1ncok 30-60%-kal kompaktabb t\u00e1rol\u00e1sa, mint az UTF-8\" src=\"\/wp-content\/uploads\/2020\/10\/0bc9f35ad2757d656801c6466dda09a8.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>Forr\u00e1s: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/521110\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438 \u043f\u0435\u0440\u0435\u0434 \u0432\u0430\u043c\u0438 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438, \u0442\u043e \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u042e\u043d\u0438\u043a\u043e\u0434. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, \u043d\u043e \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u2014 UTF-8. \u041e\u043d \u0445\u043e\u0440\u043e\u0448 \u0442\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u042e\u043d\u0438\u043a\u043e\u0434\u0430, \u043d\u0435 \u0442\u0440\u0430\u0442\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432. \u041f\u0440\u0430\u0432\u0434\u0430, \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0445 \u043d\u0435 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":95912,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-95911","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0415\u0441\u043b\u0438 \u0432\u044b.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/eshhyo-odin-velosiped-hranim-yunikodnye-stroki-na-30-60-kompaktnee-chem-utf-8\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"hu_HU\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434: \u0445\u0440\u0430\u043d\u0438\u043c \u044e\u043d\u0438\u043a\u043e\u0434\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430 30-60% \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u0435\u0435, \u0447\u0435\u043c UTF-8 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0415\u0441\u043b\u0438 \u0432\u044b.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/eshhyo-odin-velosiped-hranim-yunikodnye-stroki-na-30-60-kompaktnee-chem-utf-8\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-10-04T23:42:09+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-10-04T23:42:09+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47M\u00e9g egy ker\u00e9kp\u00e1r: a Unicode karakterl\u00e1ncokat 30-60%-kal t\u00f6m\u00f6r\u00edtettebben t\u00e1roljuk, mint az UTF-8 | ProHoster","description":"Ha \u00f6n.","canonical_url":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/eshhyo-odin-velosiped-hranim-yunikodnye-stroki-na-30-60-kompaktnee-chem-utf-8","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hu_HU","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434: \u0445\u0440\u0430\u043d\u0438\u043c \u044e\u043d\u0438\u043a\u043e\u0434\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430 30-60% \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u0435\u0435, \u0447\u0435\u043c UTF-8 | ProHoster","og:description":"\u0415\u0441\u043b\u0438 \u0432\u044b.","og:url":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/eshhyo-odin-velosiped-hranim-yunikodnye-stroki-na-30-60-kompaktnee-chem-utf-8","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-10-04T23:42:09+00:00","article:modified_time":"2020-10-04T23:42:09+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"95911","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 10:55:40","updated":"2022-09-29 03:35:04","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/95911","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/comments?post=95911"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/95911\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media\/95912"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media?parent=95911"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/categories?post=95911"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/tags?post=95911"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}