Měl by být UTF-16 považován za škodlivý?

Komentáře

  • Ve skutečnosti to není správné. Vysvětlím, že pokud napíšete " שָׁ " složený znak, který se skládá z " ש ", " ָ " a " ׁ ", vovels, pak je odstranění každého z nich logické, odstraníte jeden kódový bod stisknutím " backspace " a po stisknutí " del " odstranit všechny znaky včetně vovel. Nikdy však neprodukujete ilegální stav textu – nelegální body kódu. Situace, kdy stisknete backspace a získáte nelegální text, je tedy nesprávná.
  • CiscoIPPhone: Pokud je chyba " nahlášena několikrát, mnoha různými lidmi " a o pár let později vývojář na blogu pro vývojáře píše, že " Věřte tomu nebo ne, chování je většinou úmyslné! ", pak (mírně řečeno) mám tendenci si myslet, že to ' pravděpodobně není nejlepší rozhodnutí o designu, jaké kdy bylo učiněno. 🙂 Jen proto, že to ' s úmyslně neznamená ' to neznamená ' to není chyba.
  • Skvělý příspěvek. UTF-16 je skutečně " nejhorší z obou světů ": UTF8 má proměnnou délku, pokrývá celý Unicode, vyžaduje transformační algoritmus do a ze surových kódových bodů, omezuje se na ASCII a nemá žádné problémy s endianitou. UTF32 má pevnou délku, nevyžaduje žádnou transformaci, ale zabírá více místa a má problémy s endianitou. Zatím je to dobré, můžete použít UTF32 interně a UTF8 pro serializaci. Ale UTF16 nemá žádné výhody: Je ' závislý na endian, má ' proměnnou délku, zabírá spoustu místa, ' není kompatibilní s ASCII. Úsilí potřebné ke správnému řešení UTF16 by mohlo být vynaloženo lépe na UTF8.
  • @Ian: UTF-8 NEMÁ stejné námitky jako UTF-8. V UTF-8 nemůžete mít náhradní. UTF-8 se maskuje jako něco, čím není, ale většina programátorů používajících UTF-16 to používá špatně. Vím. Sledoval jsem je ' znovu a znovu a znovu a znovu.
  • Také UTF-8 ' t mít problém, protože s ním každý zachází jako s kódováním s proměnnou šířkou. Důvodem, proč UTF-16 má problém, je to, že s ním každý zachází jako s kódováním s pevnou šířkou.

Odpověď

Toto je stará odpověď.
Viz UTF-8 Everywhere pro nejnovější aktualizace.

Stanovisko: Ano, UTF-16 by měl být považován za škodlivý . Samotný důvod, proč existuje, je ten, že před nějakou dobou existovala mylná víra, že widechar bude tím, čím je nyní UCS-4.

Navzdory „anglocentrismu“ UTF-8 to by mělo být považováno za jediné užitečné kódování textu. Lze namítnout, že zdrojové kódy programů, webové stránky a soubory XML, názvy souborů OS a další textová rozhraní mezi počítači nikdy neměly existovat. Ale když to udělají, text není jen pro lidské čtenáře.

Na druhou stranu, režie UTF-8 je malá cena, kterou je třeba zaplatit, i když má značné výhody. Výhody, jako je kompatibilita s nevědomým kódem, který právě předává řetězce s char*. To je skvělá věc. Existuje několik užitečných znaků, které jsou v UTF-16 ZKRATNĚJŠÍ než v UTF-8.

Věřím, že všechna ostatní kódování nakonec zemřou. To znamená, že MS-Windows, Java, ICU, python přestaňte je používat jako své oblíbené. Po dlouhém výzkumu a diskusích vývojové konvence v mé společnosti zakazují používání UTF-16 kdekoli kromě volání OS API, a to i přes důležitost výkonu v našich aplikacích a skutečnost, že používáme Windows. Byly vyvinuty funkce převodu k převodu vždy předpokládaného UTF8 std::string s na nativní UTF-16, který samotný Windows nepodporuje správně .

Lidem, kteří říkají „ použijte, co je potřeba, tam, kde je to potřeba “, říkám: je obrovská výhoda používání stejného kódování všude a nevidím dostatečný důvod k tomu, udělejte jinak. Zejména si myslím, že přidání wchar_t do C ++ bylo chybou, stejně tak i doplňky Unicode k C ++ 0x. Co je ale třeba od implementací STL vyžadovat, je, že každý Parametr std::string nebo char* by byl považován za kompatibilní s unicode.

Jsem také proti „ použití přístup, který chcete . Nevidím důvod pro takovou svobodu. V předmětu textu je dost zmatku, což má za následek veškerý tento nefunkční software. Po výše uvedeném jsem přesvědčen, že programátoři musí konečně dosáhnout konsensu o UTF-8 jako o jednom správném způsobu. (Pocházím ze země, která nemluví ascii, a vyrostl jsem na Windows, takže bych měl naposledy očekávat útok na UTF-16 z náboženských důvodů.)

Rád bych se podělil o více informací o tom, jak dělám text ve Windows, a co doporučuji všem ostatním pro správnost unicode zkontrolovanou při kompilaci, snadné použití a lepší multiplatformnost kódu. Návrh se podstatně liší od toho, co se obvykle doporučuje jako správný způsob použití Unicode v systému Windows. Přesto důkladný výzkum těchto doporučení vyústil ve stejný závěr. Tady tedy je:

  • Nepoužívejte wchar_t nebo std::wstring na žádném jiném místě než v sousedním bodě API přijímající UTF-16.
  • Nepoužívejte _T("") nebo L"" literály UTF-16 (ty by měly být ze standardu vyjmuty IMO , jako součást podpory UTF-16).
  • Nepoužívejte typy, funkce nebo jejich deriváty, které jsou citlivé na _UNICODE konstantu, například LPTSTR nebo CreateWindow().
  • Přesto _UNICODE vždy definováno, vyhněte se předávání char* řetězců do WinAPI, aby se tiše kompilovaly
  • std::strings a char* kdekoli v programu jsou považovány za UTF-8 (pokud není uvedeno jinak)
  • Všechny moje řetězce jsou std::string, i když můžete předat char * nebo řetězcový literál convert(const std::string &).
  • používejte pouze funkce Win32, které přijímají widechars (LPWSTR). Nikdy ti, kteří přijímají LPTSTR nebo LPSTR. Předejte parametry tímto způsobem:

    ::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str()) 

    (Zásady používají níže uvedené převodní funkce.)

  • S řetězci MFC :

    CString someoneElse; // something that arrived from MFC. Converted as soon as possible, before passing any further away from the API call: std::string s = str(boost::format("Hello %s\n") % Convert(someoneElse)); AfxMessageBox(MfcUtils::Convert(s), _T("Error"), MB_OK); 
  • Práce se soubory, názvy souborů a fstream ve Windows:

    • Nikdy neprocházet std::string nebo const char* argumenty souboru do rodiny fstream. MSVC STL nepodporuje argumenty UTF-8, ale má nestandardní příponu, která by měla být použita následovně:
    • Převést argumenty std::string na std::wstring s Utils::Convert:

      std::ifstream ifs(Utils::Convert("hello"), std::ios_base::in | std::ios_base::binary); 

      Budeme muset ručně odstraňte převod, když se změní přístup společnosti MSVC k fstream.

    • Tento kód není multiplatformní a může být nutné jej změnit ručně v budoucnost
    • Další informace najdete v fstream výzkumném / diskusním případě unicode 4215.
    • Nikdy nevytvářejte výstupní textové soubory s jiným obsahem než UTF8
    • Nepoužívejte fopen() z důvodů RAII / OOD. V případě potřeby použijte _wfopen() konvence WinAPI výše.

// For interface to win32 API functions std::string convert(const std::wstring& str, unsigned int codePage /*= CP_UTF8*/) { // Ask me for implementation.. ... } std::wstring convert(const std::string& str, unsigned int codePage /*= CP_UTF8*/) { // Ask me for implementation.. ... } // Interface to MFC std::string convert(const CString &mfcString) { #ifdef UNICODE return Utils::convert(std::wstring(mfcString.GetString())); #else return mfcString.GetString(); // This branch is deprecated. #endif } CString convert(const std::string &s) { #ifdef UNICODE return CString(Utils::convert(s).c_str()); #else Exceptions::Assert(false, "Unicode policy violation. See W569"); // This branch is deprecated as it does not support unicode return s.c_str(); #endif } 

Komentáře

  • Nemohu ' souhlasit. Výhody utf16 oproti utf8 pro mnoho asijských jazyků zcela dominují bodům, které děláte. Je naivní doufat, že Japonci, Thajci, Číňané atd. Se tohoto kódování vzdají. Problematické střety mezi znakovými sadami nastávají, když se znakové sady většinou zdají podobné, až na rozdíly. Navrhuji standardizaci na: fixed 7bit: iso-irv-170; 8bitová proměnná: utf8; 16bitová proměnná: utf16; Opraveno 32 bitů: ucs4.
  • @Charles: děkujeme za váš příspěvek. Je pravda, že některé znaky BMP jsou v UTF-8 delší než v UTF-16. Ale řekněme to ': problém nespočívá v bajtech čínských znaků BMP, nýbrž v komplikovanosti softwarového designu. Pokud čínský programátor musí stejně navrhovat znaky s proměnnou délkou, zdá se, že UTF-8 je ve srovnání s jinými proměnnými v systému stále malou cenou, kterou je třeba zaplatit. Pokud je prostor tak důležitý, mohl by použít UTF-16 jako kompresní algoritmus, ale i tak to nebude odpovídat LZ a po LZ nebo jiné generické kompresi bude mít přibližně stejnou velikost a entropii.
  • V podstatě říkám, že zjednodušení, které nabízí kódování One, které je také kompatibilní se stávajícími programy char *, a které je dnes také nejpopulárnější, je nepředstavitelné.Je to skoro jako za starých dobrých " holých textů " dnů. Chcete otevřít soubor se jménem? Není třeba se starat o to, jaký druh unicode děláte atd. Navrhuji, abychom my, vývojáři, omezili UTF-16 na velmi speciální případy těžké optimalizace, kde malý výkon stojí za člověk-měsíce práce.
  • Linux měl při výběru interního použití UTF-8 zvláštní požadavek: kompatibilita s Unixem. Windows to ' nepotřebují, a proto když vývojáři implementovali Unicode, přidali verze UCS-2 téměř všech funkcí zpracovávajících text a vícebajtové jednoduše převedli na UCS-2 a zavolej ostatním. THey později nahradí UCS-2 UTF-16. Linux na druhé straně dodržoval 8bitové kódování, a proto používal UTF-8, protože v tomto případě je ' správnou volbou.
  • @Pavel Radzivilovsky : BTW, vaše texty o " věřím, že všechna ostatní kódování nakonec zemřou. To znamená, že MS-Windows, Java, ICU, python jej přestanou používat jako své oblíbené. " a " Zejména si myslím, že přidání wchar_t do C ++ bylo chybou, stejně jako přírůstky unicode do C ++ Ox. " jsou buď docela naivní, nebo velmi arogantní . A toto pochází od někoho, kdo kóduje doma s Linuxem a kdo je spokojený s znaky UTF-8. Abych to řekl na rovinu: To se ' nestane .

Odpovědět

Unicode kódové body nejsou znaky! Někdy to nejsou ani glyfy (vizuální formy) .

Některé příklady:

  • Kódové body římských číslic, například „ⅲ“. (Jeden znak, který vypadá jako „iii“.)
  • Znaky s diakritikou jako „á“, které lze reprezentovat buď jako jeden kombinovaný znak „\ u00e1“, nebo jako znak a oddělené diakritiku „\ u0061 \ u0301 „.
  • Znaky, jako je řecká malá sigma, které mají různé tvary středních (“ σ „) a koncových (“ ς „) pozic slov, ale které by měly být považovány za synonyma pro vyhledávání. >
  • Diskrétní pomlčka Unicode U + 00AD, která se může nebo nemusí zobrazit vizuálně, v závislosti na kontextu, a která je při sémantickém vyhledávání ignorována.

Jediné způsoby, jak provést úpravy Unicode vpravo je použít knihovnu napsanou odborníkem nebo se stát odborníkem a napsat si ji sami. Pokud počítáte pouze bodové body, žijete ve stavu hříchu.

Komentáře

  • Toto. Moc tohle. UTF-16 může způsobit problémy, ale i když budete používat UTF-32 v celém, může vám to (a bude) dělat problémy.
  • Co je to postava? Můžete definovat bod kódu jako znak a dostat se docela dobře. Pokud máte na mysli uživatelsky viditelný glyf, je to něco jiného.
  • @tchrist jistý, že pro alokaci prostoru je tato definice v pořádku, ale pro cokoli jiného? Ne tak moc. Pokud zpracováváte kombinující znak jako jediný znak (tj. Pro operaci mazání nebo " použijte prvních N znaků "), ' chovám se divně a špatně. Pokud má kódový bod význam pouze v kombinaci s alespoň jiným, nemůžete ' ho zpracovat samostatně žádným rozumným způsobem.
  • @Pacerier, toto je pozdě na večírek, ale k tomu se musím vyjádřit. Některé jazyky mají velmi velké množiny možných kombinací diakritiky (srov. Vietnamština, tj. Mệt đừ). Kombinace namísto jednoho znaku na diakritiku je velmi užitečná.
  • malá poznámka k terminologii: codepoints do odpovídají znakům unicode ; o čem Daniel tady mluví, jsou znaky vnímané uživateli , které odpovídají klastrům grafických souborů unicode

odpověď

Existuje jednoduché pravidlo, jaké formuláře transformace Unicode (UTF) použít: – utf-8 pro ukládání a komunikaci – utf-16 pro zpracování dat – můžete jít s utf-32, pokud většina použitého API platformy je utf-32 (běžné ve světě UNIX).

Většina systémů dnes používá utf-16 (Windows, Mac OS, Java, .NET, ICU , Qt). Viz také tento dokument: http://unicode.org/notes/tn12/

Zpět na „UTF-16 jako škodlivé“, Řekl bych: rozhodně ne.

Lidé, kteří se bojí náhradních prostředků (myslí si, že transformují Unicode na kódování s proměnnou délkou), nerozumí dalším (mnohem větším) složitostem, které vytvářejí mapování mezi znaky a bod kódu Unicode je velmi složitý: kombinování znaků, ligatur, selektorů variací, řídicích znaků atd.

Prostě si přečtěte tuto sérii zde http://www.siao2.com/2009/06/29/9800913.aspx a uvidíte, jak se UTF-16 stává snadným problémem.

Komentáře

  • Přidejte několik příkladů, kde je UTF-32 ve světě UNIX běžný!
  • Ne, nemáte chcete použít UTF-16 pro zpracování dat. ' je to bolest v zadku. Má všechny nevýhody UTF-8, ale žádnou z jeho výhod. UTF-8 i UTF-32 jsou jasně lepší než začarovaný hack, dříve známý jako paní UTF-16, jehož rodné jméno bylo UCS-2.
  • Včera jsem právě našel chybu ve třídě Java Core String Metoda equalsIgnoreCase (i ostatní ve třídě řetězců), která by tam nikdy nebyla, kdyby Java používala UTF-8 nebo UTF-32. V každém kódu, který používá UTF-16, jsou miliony těchto spících bomb, a já jsem z nich nemocný a unavený. UTF-16 je brutální neštovice, která trápí náš software zákeřnými chybami navždy a navždy. Je zjevně škodlivá a měla by být zastaralá a zakázaná.
  • @tchrist Wow, což je funkce, která není náhradní (protože byla napsána, když žádná neexistovala, a je bohužel dokumentována takovým způsobem, že to pravděpodobně nemožné přizpůsobit – určuje .toUpperCase (char)) bude mít za následek špatné chování? ' Uvědomujete si, že funkce UTF-32 s neaktuální mapou bodů kódu by to ' nezvládla lépe? Celé rozhraní Java API také nenahrazuje zvlášť dobře a složitější body o Unicode vůbec ne – a s pozdějším použitým kódováním by vůbec nezáleželo ' na tom.
  • -1: Bezpodmínečný .Substring(1) v .NET je triviální příklad něčeho, co narušuje podporu všech Unicode jiných než BMP. Všechno , které používá UTF-16, má tento problém; je ' příliš snadné jej považovat za kódování s pevnou šířkou a problémy vidíte příliš zřídka. Díky tomu je aktivně škodlivé kódování, pokud chcete podporovat Unicode.

Odpovědět

Ano, absolutně.

Proč? Souvisí to s cvičebním kódem .

Pokud se podíváte na tyto statistiky využití kódového bodu na velkém korpusu od Toma Christiansena „uvidíte, že trans-8bitové kódové body BMP se používají v několika řádech, pokud jsou větší než kódové body jiné než BMP:

 2663710 U+002013 ‹–› GC=Pd EN DASH 1065594 U+0000A0 ‹ › GC=Zs NO-BREAK SPACE 1009762 U+0000B1 ‹±› GC=Sm PLUS-MINUS SIGN 784139 U+002212 ‹−› GC=Sm MINUS SIGN 602377 U+002003 ‹ › GC=Zs EM SPACE 544 U+01D49E ‹𝒞› GC=Lu MATHEMATICAL SCRIPT CAPITAL C 450 U+01D4AF ‹𝒯› GC=Lu MATHEMATICAL SCRIPT CAPITAL T 385 U+01D4AE ‹𝒮› GC=Lu MATHEMATICAL SCRIPT CAPITAL S 292 U+01D49F ‹𝒟› GC=Lu MATHEMATICAL SCRIPT CAPITAL D 285 U+01D4B3 ‹𝒳› GC=Lu MATHEMATICAL SCRIPT CAPITAL X 

Vezměte výrok TDD: „Netestovaný kód je poškozený kód“ a přeformulujte jej jako „nevycvičený kód je poškozený kód“ a přemýšlejte, jak často se programátoři musí vypořádat s kódovými body, které nejsou BMP.

Chyby související s nezabýváním se UTF-16 jako kódováním s proměnnou šířkou zůstanou mnohem častěji bez povšimnutí než ekvivalentní chyby v UTF-8 . Některé programovací jazyky stále nezaručujeme, že vám místo UCS-2 poskytneme UTF-16, a některé takzvané programovací jazyky na vysoké úrovni nabízejí přístup k kódovým jednotkám namísto kódových bodů (dokonce i C vám má poskytnout přístup k kódovým bodům, pokud používáte wchar_t, bez ohledu na to, jaké jsou plat formuláře mohou dělat).

Komentáře

  • " Chyby související s neřešením UTF-16 jako kódování s proměnnou šířkou bude mnohem pravděpodobněji bez povšimnutí než ekvivalentní chyby v UTF-8. " Toto je jádro problému, a tedy správná odpověď.
  • přesně. Pokud je vaše manipulace s UTF-8 viditelná, bude to ' okamžitě zřejmé. Pokud je vaše manipulace s UTF-8 nahraná, ' si všimnete, pouze pokud vložíte neobvyklé znaky Han nebo matematické symboly.
  • Velmi pravdivé, ale na druhé straně ruka, na co jsou jednotkové testy, pokud byste měli záviset na štěstí při hledání chyb v méně častých případech?
  • @musiphil: tak, kdy jste naposledy vytvořili jednotkový test pro znaky jiné než BMP?
  • K dalšímu upřesnění mého dřívějšího prohlášení: ani u UTF-8 si nemůžete být jisti, že jste pokryli všechny případy poté, co jste viděli několik pracovních příkladů. Totéž s UTF-16: musíte otestovat, zda váš kód funguje jak s náhradníky, tak s náhradníky. (Někdo by mohl dokonce namítnout, že UTF-8 má nejméně čtyři hlavní případy, zatímco UTF-16 má jen dva.)

Odpověď

Navrhuji, aby myšlení UTF-16 mohlo být považováno za škodlivé, říká, že musíte získat lepší pochopení unicode .

Vzhledem k tomu, že jsem byl odmítnut, abych předložil svůj názor na subjektivní otázku, dovolte mi to rozvinout. Co přesně vám na UTF-16 vadí? Dáváte přednost tomu, kdyby bylo všechno zakódováno v UTF-8? UTF-7? Nebo co takhle UCS-4? Určité aplikace samozřejmě nejsou navrženy tak, aby zpracovávaly everysingle kód znaků – ale jsou nezbytné, zejména v dnešní globální informační doméně, pro komunikaci mezi mezinárodními hranicemi.

Ale ve skutečnosti, pokud máte pocit, že UTF-16 by měl být považován za škodlivý, protože je matoucí nebo může být nesprávně implementován (unicode určitě může být), jaká metoda kódování znaků by byla považována za neškodnou?

EDIT: K objasnění: Proč považovat nesprávnou implementaci standardu za odraz kvality samotné normy? Jak jiní později poznamenali, pouhé proto, že aplikace nevhodně používá nástroj, neznamená, že nástroj sám o sobě je vadný. Pokud by tomu tak bylo, mohli bychom pravděpodobně říci věci jako „klíčové slovo var považováno za škodlivé“ nebo „vlákno považované za škodlivé“. Myslím, že otázka zaměňuje kvalitu a povahu standardu s obtížemi, které mají mnozí programátoři při implementaci a správné používání, což podle mého názoru pramení spíše z jejich nedostatečného porozumění fungování unicode, než ze samotného unicode.

Komentáře

  • -1: Co takhle oslovit některé z objektů Artyom ' s raději než jen patronovat jej?
  • BTW: Když jsem začal psát tento článek, málem jsem chtěl napsat " Je třeba uvažovat o Joelovi v článku Unicode o Unicode škodlivé " protože existuje mnoho chyb. Například: kódování utf-8 trvá až 4 znaky a ne 6. Rovněž nerozlišuje mezi UCS-2 a UTF-16, které se opravdu liší – a ve skutečnosti způsobují problémy, o kterých mluvím.
  • Také je třeba poznamenat, že když Joel napsal tento článek, standard UTF-8 BOL 6 bytů, ne 4. RFC 3629 změnil standard na 4 byty několik měsíců PO napsání článku. Jako většina čehokoli na internetu se vyplatí číst z více než jednoho zdroje a být si vědom stáří svých zdrojů. Odkaz nebyl ' zamýšlen jako " konec vše ", ale spíše výchozí bod.
  • Chtěl bych použít: utf-8 nebo utf-32, což jsou: kódování s proměnnou délkou téměř ve všech případech (včetně BMP) nebo kódování s pevnou délkou vždy.
  • @iconiK: Nebuď hloupý. UTF-16 absolutně není de facto standard pro zpracování textu. Ukaž mi programovací jazyk vhodnější pro zpracování textu, který Perl, který vždy (dobře, pro více než desetiletí) interně používaly abstraktní znaky s podkladovou reprezentací UTF-8. Z tohoto důvodu každý program Perl automaticky zpracovává všechny Unicode, aniž by uživatel musel neustále opičit s idiotskými náhradníky. Délka řetězce je jeho počet v kódových bodech, nikoli v kódových jednotkách. Cokoli jiného je naprostá hloupost, která vede zpět k zpětné kompatibilitě.

Odpověď

Na Utf není nic špatného 16 kódování. Ale jazyky, které považují 16bitové jednotky za znaky, by měly být pravděpodobně považovány za špatně navržené. Mít typ s názvem „char„, který ne vždy představuje znak, je docela matoucí. Vzhledem k tomu, že většina vývojářů očekává, že typ char bude představovat bod nebo znak kódu, hodně kódu se pravděpodobně rozbije, když bude vystaveno postavám mimo BMP.

Všimněte si však, že ani použití utf-32 neznamená, že každý 32- bod bitového kódu bude vždy představovat znak. Kvůli kombinování znaků se skutečný znak může skládat z několika kódových bodů. Unicode nikdy není triviální.

BTW. Pravděpodobně existuje stejná třída chyb s platformami a aplikacemi, které očekávají, že znaky budou 8bitové, a které jsou napájeny Utf-8.

Komentáře

  • V případě Java ' s, pokud se podíváte na jejich časovou osu ( java.com/en/javahistory/timeline.jsp), vidíte, že k primárnímu vývoji řetězce došlo, když Unicode měl 16 bitů (změnilo se to v roce 1996). Museli využít schopnost zvládnout jiné body kódu než BMP, tedy zmatek.
  • @Kathy: Není to však pro C # omluva. Obecně souhlasím s tím, že by měl existovat CodePoint typ, který drží jeden bod kódu (21 bitů), CodeUnit typ, který drží jedna kódová jednotka (16 bitů pro UTF-16) a typ Character by v ideálním případě musely podporovat kompletní grafém. Ale díky tomu je funkčně ekvivalentní String
  • Tato odpověď je téměř dva roky stará, ale mohu ' nepomůže, ale okomentuje to. " Mít typ s názvem ' char ', který ne vždy představuje znak, je hezké matoucí. " A přesto ho lidé používají po celou dobu v jazyce C a podobně k reprezentaci celočíselných dat, která lze uložit do jednoho bajtu.
  • A I ' jsem viděl spoustu kódu C, který ' nezpracovává kódování znaků správně.
  • C # má jinou výmluvu: byl navržen pro Windows a Windows byl postaven na UCS-2 (' je velmi nepříjemné, že ani dnes Windows API nemohou podpora UTF-8). Navíc si myslím, že Microsoft chtěl kompatibilitu Java (.NET 1.0 měl knihovnu kompatibility Java, ale podporu Java velmi rychle zrušili – hádám ' kvůli Sun ' žaloba na MS?)

Odpověď

Moje osobní volba je vždy používat UTF-8. Je to standard v Linuxu téměř pro všechno. Je zpětně kompatibilní s mnoha staršími aplikacemi. Existuje velmi minimální režie, pokud jde o extra prostor používaný pro jiné než latinské znaky oproti ostatním formátům UTF, a existuje značná úspora prostoru pro latinské znaky. Na webu vládnou latinské jazyky a myslím, že v dohledné budoucnosti budou. A abychom se zabývali jedním z hlavních argumentů v původním příspěvku: téměř každý programátor si je vědom, že UTF-8 bude někdy obsahovat vícebajtové znaky. Ne každý s tím zachází správně, ale obvykle si je vědom, což je více, než lze říci o UTF-16. Samozřejmě si musíte vybrat ten nejvhodnější pro vaši aplikaci. Proto je na prvním místě více než jedna.

Komentáře

  • UTF-16 je pro cokoli uvnitř BMP jednodušší, že ' proč se používá tak široce. Ale i já ' jsem fanouškem UTF-8, nemá problémy ani s bajtovým uspořádáním, které funguje ve svůj prospěch.
  • Teoreticky ano. V praxi existují věci jako například UTF-16BE, což znamená UTF-16 ve velkém endianu bez BOM. To není něco, co jsem vymyslel, jedná se o skutečné kódování povolené ve značkách ID3v2.4 (značky ID3v2 sají, ale jsou bohužel široce používány). A v takových případech musíte endiannost definovat externě, protože samotný text neobsahuje ' kusovník. UTF-8 je vždy psán jedním způsobem a nemá ' takový problém.
  • Ne, UTF-16 není jednodušší. Je to těžší. Zavádí vás a klame, abyste si mysleli, že má pevnou šířku. Veškerý takový kód je rozbitý a všechno navíc, protože si toho nevšimnete, dokud nebude pozdě. PŘÍPAD V BODU: Právě jsem včera našel další hloupou chybu UTF-16 v základních knihovnách Java, tentokrát v String.equalsIgnoreCase, která byla ponechána v buindery UCS-2 braindeath, a tak selže v 16/17 platných bodech kódu Unicode. Jak dlouho ten kód existuje? Žádná výmluva pro to, že to bude kočárek. UTF-16 vede k naprosté hlouposti a nehodě, která čeká, až se stane. Spustit křik z UTF-16.
  • @tchrist One musí být velmi neznalý vývojář, aby neví, že UTF-16 nemá pevnou délku. Pokud začnete s Wikipedií, přečtete si úplně nahoře toto: " Vytvoří výsledek proměnné délky jedné nebo dvou 16bitových kódových jednotek na kódový bod ". Unicode FAQ říká totéž: unicode.org/faq//utf_bom.html#utf16-1 . Nevím ', jak UTF-16 může klamat kohokoli, pokud je všude napsáno, že má proměnnou délku. Pokud jde o metodu, nikdy nebyla navržena pro UTF-16 a neměla by být ' považována za Unicode, tak jednoduchý.
  • @tchrist Máte zdroj pro vaše statistiky? I když jsou dobří programátoři vzácní, myslím, že je to dobré, protože se stáváme cennějšími. 🙂 Pokud jde o rozhraní Java API, části založené na char mohou být nakonec zastaralé, ale to nezaručuje, že nebudou použity ' t. A rozhodně nebudou ' odstraněny z důvodů kompatibility.

Odpovědět

Existuje kódování, které používá symboly pevné velikosti. Určitě myslím UTF-32. Ale 4 bajty pro každý symbol jsou příliš hodně promarněného prostoru, proč bychom jej používali v každodenních situacích?

Podle mého názoru většina problémů vyplývá ze skutečnosti, že některý software spadl za standardem Unicode, ale nebyli připraveni situaci napravit. Opera, Windows, Python, Qt – všechny se objevily dříve, než se UTF-16 stal všeobecně známým nebo dokonce vznikl. Mohu však potvrdit, že v Opera, Průzkumníkovi Windows a Poznámkovém bloku již nejsou problémy se znaky mimo BMP (alespoň na mém PC). Ale stejně, pokud programy nerozpoznávají náhradní páry, pak nepoužívají UTF-16. Ať už při řešení těchto programů nastanou jakékoli problémy, nemají nic společného se samotným UTF-16.

Myslím si však, že problémy staršího softwaru pouze s podporou BMP jsou poněkud přehnané. Znaky mimo BMP se setkávají pouze ve velmi specifických případech a oblastech. Podle oficiálních nejčastějších dotazů Unicode „by dokonce i ve východoasijských textech měl být výskyt náhradních párů v průměru méně než 1% veškerého úložiště textu v průměru“.Samozřejmě, znaky mimo BMP by neměly být zanedbávány , protože program jinak není v souladu s Unicode, ale většina programů není určena pro práci s texty obsahujícími takové znaky. Proto, pokud se tak nestane “ Nepodporujeme to, je to nepříjemné, ale ne katastrofa.

Nyní pojďme zvážit alternativu. Pokud by UTF-16 neexistovalo, neměli bychom kódování, které by bylo vhodné pro text, který není ASCII, a veškerý software vytvořený pro UCS-2 by musel být zcela přepracován, aby zůstal kompatibilní s Unicode. Ten s největší pravděpodobností by jen zpomalil přijetí Unicode. Také bychom nebyli schopni udržet kompatibilitu s textem v UCS-2, jako to dělá UTF-8 ve vztahu k ASCII.

Nyní, odložíme-li všechny starší problémy, jaké jsou argumenty proti kódování sám o sobě? Opravdu pochybuji, že vývojáři dnes nevědí, že UTF-16 má proměnlivou délku, je napsán všude, kde se používá Wikipedia. UTF-16 je mnohem méně obtížné analyzovat než UTF-8, pokud někdo poukázal na složitost jako na možný problém. Také je mylné si myslet, že je snadné pokazit stanovení délky řetězce pouze v UTF-16. Pokud používáte UTF-8 nebo UTF-32, měli byste si být vědomi toho, že jeden bod kódu Unicode nemusí nutně znamenat jeden znak. Kromě toho si nemyslím, že proti kódování existuje něco podstatného.

Proto si nemyslím, že samotné kódování by mělo být považováno za škodlivé. UTF-16 je kompromisem mezi jednoduchostí a kompaktností a při použití toho, co je potřeba, není na škodu V některých případech musíte zůstat kompatibilní s ASCII a potřebujete UTF-8, v některých případech chcete pracovat s Hanovými ideografy a šetřit místo pomocí UTF-16, v některých případech potřebujete univerzální reprezentace postav -délkové kódování. Použijte to, co je vhodnější, prostě to udělejte správně.

Komentáře

  • To ' je poněkud zamyšlený, anglocentrický pohled, Malcolm. ASCII je pro USA téměř srovnatelné s " ASCII – zbytek světa by k nám měl zapadat ".
  • Vlastně jsem ' m z Ruska a neustále se setkávám s cyrilikou (včetně mých vlastních programů), takže ' Nemyslím si, že mám anglocentrický pohled. 🙂 Zmínka o ASCII není zcela vhodná, protože ' není v Unicode a nepodporuje ' konkrétní znaky. UTF-8, UTF-16, UTF-32 podporují stejné mezinárodní znakové sady, jsou určeny pouze pro použití v jejich konkrétních oblastech. A to je přesně moje myšlenka: pokud používáte převážně angličtinu, použijte UTF-8, pokud používáte převážně azbuku, použijte UTF-16, pokud používáte starověké jazyky, použijte UTF-32. Docela jednoduché.
  • " Není to pravda, asijské skripty jako japonština, čínština nebo arabština patří do BMP také. Samotný BMP je ve skutečnosti velmi velký a rozhodně dostatečně velký, aby zahrnoval všechny skripty používané v dnešní době " To je všechno tak špatné. BMP obsahuje 0xFFFF znaků (65536). Samotná čínština má víc než to. Čínské standardy (GB 18030) mají více než to. Unicode 5.1 již přidělil více než 100 000 znaků.
  • @Marcolm: " Samotný BMP je ve skutečnosti velmi velký a určitě dostatečně velký, aby zahrnoval všechny skripty používané v dnešní době " Není pravda. V tomto okamžiku již Unicode přidělil asi 100 000 znaků, což je mnohem více, než může pojmout BMP. Mimo BMP jsou velké kusy čínských znaků. A některé z nich vyžaduje GB-18030 (povinný čínský standard). Další jsou vyžadovány (nepovinnými) japonskými a korejskými normami. Pokud se tedy pokusíte na těchto trzích cokoli prodat, potřebujete podporu BMP.
  • Cokoliv, co používá UTF-16, ale dokáže zpracovat pouze úzké znaky BMP, ve skutečnosti UTF-16 nepoužívá. Je buggy a rozbité. Předpoklad OP je zdravý: UTF-16 je škodlivý, protože vede na ï ve lidi k psaní poškozeného kódu. Buď zvládnete text Unicode, nebo ne. Pokud nemůžete, vybíráte podmnožinu, která je stejně hloupá jako zpracování textu pouze v ASCII.

Odpovědět

Roky internacionalizace Windows, zejména ve východoasijských jazycích, mě mohly poškodit, ale já se přikláním k UTF-16 pro interní reprezentaci řetězců v programu a UTF-8 pro síťové nebo souborové ukládání prostého textu- jako dokumenty. UTF-16 lze obvykle ve Windows zpracovat rychleji, takže to je hlavní výhoda používání UTF-16 ve Windows.

Provedení skoku k UTF-16 dramaticky zlepšilo adekvátnost průměrné manipulace s produkty. mezinárodní text.Existuje pouze několik úzkých případů, kdy je třeba uvažovat o náhradních párech (odstranění, vložení a zalomení řádku, v zásadě), a průměrný případ je většinou přímý průchod. A na rozdíl od dřívějších kódování, jako jsou varianty JIS, omezuje UTF-16 náhradní páry na velmi úzký rozsah, takže kontrola je opravdu rychlá a funguje dopředu a dozadu.

Je pravda, že je zhruba stejně rychlá správně – kódovaný UTF-8. Existuje ale také mnoho nefunkčních aplikací UTF-8, které nesprávně kódují náhradní páry jako dvě sekvence UTF-8. UTF-8 tedy nezaručuje ani záchranu.

IE zpracovává náhradní páry rozumně dobře od roku 2000 nebo tak, i když je obvykle převádí ze stránek UTF-8 na interní reprezentaci UTF-16; „Jsem si docela jistý, že Firefox to má správně, takže mě vůbec nezajímá, co Opera dělá.

UTF-32 (aka UCS4) je pro většinu aplikací zbytečný, protože je tak prostorově náročný, takže je to do značné míry nestartér.

Komentáře

  • Nedostal jsem ' úplně vaše komentovat UTF-8 a náhradní páry. Náhradní páry je pouze koncept, který má smysl v kódování UTF-16, že? Možná, že kód, který převádí přímo z kódování UTF-16 na kódování UTF-8, se může pokazit, a to V takovém případě je problémem nesprávné čtení UTF-16, nikoli psaní UTF-8. Je to pravda?
  • O čem mluví Jason ' je software, který záměrně implementuje UTF-8 tímto způsobem: vytvořte náhradní pár a poté UTF-8 en kódovat každou polovinu zvlášť. Správný název pro toto kódování je CESU-8, ale Oracle jej (například) nesprávně uvádí jako UTF-8. Java používá podobné schéma pro serializaci objektů, ale je ' jasně zdokumentováno jako " Modifikovaný UTF-8 " a pouze pro interní použití. (Nyní, kdybychom mohli přimět lidi, aby si přečetli tuto dokumentaci a přestali nevhodně používat DataInputStream # readUTF () a DataOutputStream # writeUTF () …)
  • AFAIK, UTF-32 je stále kódování s proměnnou délkou, a nerovná se UCS4, což je specifický rozsah kódového bodu.
  • @Eonil, UTF-32 bude vždy odlišitelný od UCS4, pokud máme standard Unicode, který obsahuje něco jako UCS5 nebo větší.
  • @JasonTrue Stále jsou shodné pouze výsledky, které nejsou zaručeny designem. Totéž se stalo v 32bitovém adresování paměti, Y2K, UTF16 / UCS2. Nebo máme nějakou záruku této rovnosti? Pokud ano, rád bych to využil. Ale ' nechci napsat možný rozbitný kód. Píšu kód na úrovni znaků a nedostatek zaručeného způsobu překódování mezi kódovým bodem UTF < – > mě hodně štve .

Odpověď

UTF-8 je určitě způsob, jak jít, případně doplněný UTF-32 pro interní použití v algoritmech, které vyžadují vysoce výkonný náhodný přístup (ale ignoruje kombinování znaků).

UTF-16 i UTF-32 (stejně jako jejich varianty LE / BE) trpí problémy endianess, takže by měli nikdy nepoužívejte externě.

Komentáře

  • I v UTF-8 je možný náhodný přístup v konstantním čase, stačí použít kódové jednotky místo kódových bodů. Možná potřebujete skutečný náhodný přístup k bodům kódu, ale ' jsem nikdy neviděl případ použití a ' je stejně pravděpodobné, že budete chtít namísto toho náhodný přístup ke clusterům grapheme.

Odpověď

UTF-16? rozhodně škodlivé. Jenom moje zrnko soli, ale v programu existují přesně tři přijatelná kódování pro text:

  • ASCII: při řešení věcí na nízké úrovni (např. Mikrokontroléry), které si nemohou dovolit nic lepšího
  • UTF8: úložiště na médiích s pevnou šířkou, jako jsou soubory
  • integer codepoints („CP“?): pole největších celých čísel, které jsou vhodné pro váš programovací jazyk a platforma (rozpadá se na ASCII v limitu nízkých resorcí). Mělo by být int32 na starších počítačích a int64 na cokoli se 64bitovým adresováním.

  • Je zřejmé, že rozhraní pro použití staršího kódu jaké kódování je potřeba, aby starý kód správně fungoval.

Komentáře

  • @simon buchan, U+10ffff max vyjde z okna, když (ne pokud) jim dojdou kódové body. To znamená, že použití int32 v systému p64 pro rychlost je pravděpodobně bezpečné, protože pochybuji, že ' před vámi iv id = „1d3184“ překročí U+ffffffff f537 „>

byl nucen přepsat svůj kód pro 128bitové systémy kolem roku 2050. (To je důvod " použít největší int, který je vhodný " na rozdíl od " největšího dostupného " (což by pravděpodobně bylo int256 nebo bignums nebo tak něco).)

  • @David: Unicode 5.2 kóduje 107 361 kódových bodů.Existuje 867 169 nevyužitých kódových bodů. " když je " jen hloupý. Kódový bod Unicode je definován jako číslo od 0 do 0x10FFFF, vlastnost, na které závisí UTF-16. (Rovněž rok 2050 se zdá být velmi nízkým odhadem pro 128bitové systémy, když 64bitový systém dokáže pojmout celý internet v ' s adresním prostoru.)
  • @David: Vaše " když " odkazoval na vyčerpání kódových bodů Unicode, ne 128bitový přepínač, který, ano, bude v příštích několika stoletích. Na rozdíl od paměti nedochází k exponenciálnímu růstu znaků, takže konsorcium Unicode má konkrétně zaručeno, že nikdy nepřidělí kódový bod nad U+10FFFF. Toto je opravdu jedna z těch situací, kdy 21 bitů stačí komukoli.
  • @Simon Buchan: Alespoň do prvního kontaktu. 🙂
  • Unicode slouží k zajištění toho, že nad U + FFFF nebudou žádné body kódu.
  • Odpověď

    Unicode definuje body kódu až 0x10FFFF (1 114 112 kódů), všechny aplikace běžící ve vícejazyčném prostředí se zabývají s řetězci / názvy souborů atd. by to mělo správně zpracovat.

    Utf-16 : pokrývá pouze 1112 064 kódy. Ačkoli ti na konci Unicode jsou z letadel 15-16 (Oblast pro soukromé použití). V budoucnu nemůže dále růst, kromě porušení konceptu Utf-16 .

    Utf-8 : pokrývá teoreticky 2 216 757 376 kódů. Aktuální rozsah kódů Unicode lze vyjádřit maximálně 4 bajtovou sekvencí. Netrpí problémem bajtů , je „kompatibilní“ s ascii.

    Utf-32 : teoreticky zahrnuje 2 ^ 32 = 4 294 967 296 kódů. V současné době není kódován s proměnnou délkou a pravděpodobně ani v budoucnu nebude.

    Tato fakta jsou vysvětlující. Nerozumím obhajování obecného používání Utf-16 . Je kódován s proměnnou délkou (nelze k němu získat index), má problémy pokrýt celý rozsah Unicode i v současnosti, bajtové pořadí musí být zpracováno atd. Nevidím žádnou výhodu kromě toho, že je nativně používán ve Windows a na některých dalších místech. I když při psaní kódu pro více platforem je pravděpodobně lepší použít Utf-8 nativně a převádět pouze v koncových bodech způsobem závislým na platformě (jak již bylo navrženo). Pokud je nutný přímý přístup pomocí indexu a paměť není problém, měl by se použít Utf-32 .

    Hlavním problémem je, že mnoho programátorů zabývajících se Windows Unicode = Utf-16 ani neví, nebo ignoruje skutečnost, že má kódování s proměnnou délkou.

    Způsob, jakým je to obvykle v platformě * nix , je docela dobrý, řetězce c (char *) interpretované jako Utf-8 kódované, široké řetězce c (wchar_t *) interpretované jako Utf-32 .

    Komentáře

    • Poznámka: UTF -16 zahrnuje All Unicode, protože Unicode Consortium rozhodlo, že 10FFFF je NEJLEPŠÍ rozsah Unicode a definuje UTF-8 maximální délku 4 bajty a výslovně vylučuje rozsah 0xD800-0xDFFF z rozsahu platných kódových bodů a tento rozsah se používá k vytvoření náhradní páry. Takže každý platný text Unicode může být reprezentován každým z těchto kódování. Také o růstu do budoucnosti. Nezdá se, že by ' vypadalo, že 1 milion bodů kódu by v daleké budoucnosti nestačil.
    • @Kerrek: Nesprávně: UCS-2 není platný Unicode kódování. Všechna kódování UTF- * podle definice mohou představovat jakýkoli bod kódu Unicode, který je legální pro výměnu. UCS-2 může představovat mnohem méně než to, plus několik dalších. Opakování: UCS-2 není platné kódování Unicode, jakékoli jiné než ASCII.
    • " Nerozumím obhajování obecného použití Utf- 8 . Je kódován s proměnnou délkou (nelze k němu získat index) "
    • @Ian Boyd, potřeba přístupu k jednotlivým znakům řetězce v náhodném přístupu je neuvěřitelně přehnané. Je to asi tak běžné jako chtít vypočítat úhlopříčku matice znaků, což je velmi vzácné. Řetězce jsou prakticky vždy zpracovávány postupně a protože přístup k UTF-8 char N + 1 za předpokladu, že jste na UTF-8 char N je O (1), není zde žádný problém. Existuje překvapivě malá potřeba náhodného přístupu k řetězcům. Ať už si myslíte, že za úložný prostor stojí místo UTF-32 místo UTF-8, je to váš vlastní názor, ale pro mě to není problém.
    • @tchrist, udělám vaše řetězce jsou prakticky vždy zpracovány sekvenčně, pokud zahrnete reverzní iteraci jako " sekvenční " a roztáhnete to o trochu další srovnání koncového konce řetězec na známý řetězec. Dva velmi běžné scénáře jsou zkrácení mezer na konci řetězců a kontrola přípony souboru na konci cesty.

    Odpověď

    Přidejte toto do seznamu:

    Prezentovaný scénář je jednoduchý (ještě jednodušší, protože ho zde představím, než byl původně!) ): 1. WinForms TextBox sedí na formuláři, prázdném. Má MaxLength nastavenou na 20 .

    2. Uživatel zadá do TextBoxu, nebo možná vloží do něj text.

    3. Bez ohledu na to, co do TextBoxu napíšete nebo vložíte, máte omezeno na 20, i když bude soucitně pípat na text nad 20 (YMMV zde; změnil jsem své zvukové schéma aby mi ten efekt dal!).

    4. Malý balíček textu je poté odeslán někam jinam, aby zahájil vzrušující dobrodružství.

    Toto je nyní snadný scénář a každý si jej může zapsat ve svém volném čase. Právě jsem to napsal ve více programovacích jazycích pomocí WinForms, protože jsem se nudil a nikdy jsem to nezkoušel. A s textem ve více skutečných jazycích, protože jsem tak zapojen a mám více rozložení klávesnice, než kdokoli jiný v celém šíleném vesmíru.

    Dokonce jsem pojmenoval formulář Magic Carpet Ride , který pomohl zmírnit nudu.

    To nefungovalo, protože to stojí za to.

    Takže jsem místo toho zadal následujících 20 znaků do mé Magic Carpet Ride formuláře:

    0123401234012340123 𠀀

    Uh oh.

    Ten poslední znak je U + 20000, první Ideograf Unicode rozšíření B (aka U + d840 U + dc00, jeho blízkým přátelům, za které se nestydí za to, aby byli před tím zbaveni) ….

    zde zadejte popis obrázku

    A nyní tu máme míčovou hru.

    Protože když TextBox. MaxLength hovoří o

    Získá nebo nastaví maximální počet znaků, které lze ručně zadat do textového pole.

    ve skutečnosti to znamená

    Získává nebo nastavuje maximální počet tresek UTF-16 LE Jednotky, které lze ručně zadat do textového pole a nemilosrdně zkrátí živé kecy z jakéhokoli řetězce, který se pokouší hrát roztomilé hry s představou lingvistického charakteru, že pouze někoho tak posedlého, jako je ten Kaplanův kolega, bude považovat za urážlivého (geez, že potřebuje dostat se dál!).

    Pokusím se zjistit, jak aktualizovat dokument ….
    Pravidelní čtenáři, kteří pamatujte, že moje série UCS-2 až UTF-16 si všimne mého neštěstí se zjednodušující představou TextBox.MaxLength a jak by to mělo zvládnout minimálně v tomto případě, kdy jeho drakonické chování vytváří neplatnou sekvenci, kterou ostatní části .NET Framework mohou vyvolat

    • System.Text.EncoderFallbackException : Nelze přeložit znak Unicode \ uD850 v indexu 0 na zadanou kódovou stránku. *

    Výjimka, pokud tento řetězec předáte jinde v rámci .Net Framework (jak to dělal můj kolega Dan Thompson).

    Nyní je v pořádku, možná celá řada UCS-2 až UTF-16 je mimo dosah mnoha lidí.
    Ale není „Není rozumné očekávat, že TextBox.Text nevyprodukuje System.String , který nezpůsobí vyhodení jiného kousku .Net Framework? Myslím, že to není tak, jako by na ovládacím prvku byla šance v podobě nějaké události, která vám řekne o nadcházejícím zkrácení, kde můžete snadno přidat chytřejší ověření – ověření, které samotné ovládání nevadí. jděte tak daleko, že říkáte, že tato punková kontrola porušuje bezpečnostní smlouvu, která může dokonce vést k bezpečnostním problémům, pokud můžete třídu způsobit neočekávané výjimky pro ukončení aplikace jako hrubý druh odmítnutí služby. Proč by měl jakýkoli proces nebo metoda WinForms nebo algoritmus nebo technika produkují neplatné výsledky?

    Zdroj: Michael S.Blog společnosti Kaplan MSDN

    Komentáře

    • Díky, velmi dobrý odkaz! ' Přidal jsem ji do seznamu problémů v otázce.

    Odpovědět

    Nemusím nutně říkat, že UTF-16 je škodlivý. Není to elegantní, ale slouží to zpětné kompatibilitě s UCS-2, stejně jako GB18030 s GB2312 a UTF-8 s ASCII.

    Ale zásadní změna ve struktuře Unicode ve středním proudu, poté, co Microsoft a Sun vytvořily obrovské API kolem 16bitových znaků, bylo škodlivé. Neschopnost šířit povědomí o změně byla více škodlivá.

    Komentáře

    • UTF-8 je nadmnožinou ASCII , ale UTF-16 NENÍ nadmnožinou UCS-2. Ačkoli je to téměř nadmnožina, správné kódování UCS-2 do UTF-8 vede k ohavnosti známé jako CESU-8; UCS-2 nemá ' náhradní znaky, pouze obyčejné body kódu, takže musí být překládány jako takové. Skutečnou výhodou UTF-16 je, že je ' snazší upgradovat kódovou základnu UCS-2 než úplné přepsání pro UTF-8. Zvláštní, hm?
    • Jistě, technicky UTF-16 není ' ta nadmnožinou UCS-2, ale kdy kdy byly U + D800 až U + DFFF > použit na cokoli kromě náhradních UTF-16?
    • Nezáleží na tom '. Jakékoli jiné zpracování než slepé procházení bytestreamem vyžaduje dekódování náhradních párů, což ' nemůžete udělat, pokud ' znovu zacházíte jako UCS-2.

    Odpověď

    UTF-16 je nejlepší kompromis mezi manipulací a prostorem a proto ho většina hlavních platforem (Win32, Java, .NET) používá pro interní reprezentaci řetězců.

    Komentáře

    • -1, protože UTF-8 bude pravděpodobně menší nebo se výrazně neliší. U některých asijských skriptů jsou UTF-8 tři bajty na glyf, zatímco UTF-16 jsou pouze dva, ale to je vyváženo tím, že UTF-8 je pouze jeden bajt pro ASCII (který se často objevuje i v asijských jazycích v názvech produktů, příkazech a podobných věcech). Dále v uvedených jazycích glyf vyjadřuje více informací než latinský znak, takže je oprávněný aby to zabralo více místa.
    • Nenazýval bych kombinací wor Strany obou možností dobrý kompromis.
    • Není to ' jednodušší než UTF-8. Je to ' s proměnnou délkou.
    • Ponecháme stranou debaty o výhodách UTF-16: To, co jste citovali, není důvod pro Windows, Java nebo .NET používající UTF-16. Windows a Java se datují do doby, kdy Unicode bylo 16bitové kódování. UCS-2 byl tehdy rozumnou volbou. Když se Unicode stal 21bitovým kódováním, migrace na UTF-16 byla tou nejlepší volbou, kterou existující platformy měly. To nemělo nic společného se snadnou manipulací nebo prostorovými kompromisy. ' je to jen otázka dědictví.
    • .NET zde zdědí dědictví Windows.

    Odpověď

    Nikdy jsem nepochopil smysl UTF-16. Pokud chcete prostorově nejefektivnější reprezentaci, použijte UTF-8. Pokud chcete mít možnost považujte text za pevnou délku, použijte UTF-32. Pokud nechcete ani jeden, použijte UTF-16. Ještě horší je, že všechny běžné znaky (základní vícejazyčná rovina) v UTF-16 se vejdou do jediného kódu, chyby, které předpokládají že UTF-16 má pevnou délku, bude subtilní a těžké ho najít, zatímco pokud se pokusíte to udělat pomocí UTF-8, váš kód rychle a hlasitě selže, jakmile se pokusíte internacionalizovat.

    Odpověď

    Protože ještě nemůžu komentovat, zveřejňuji to jako odpověď, protože se zdá, že nemohu jinak kontaktovat autory utf8everywhere.org. Je škoda, že automaticky nezískám privilegium na komentář, protože v jiných výměnných zásobách mám dostatečnou reputaci.

    Toto je míněno jako komentář k stanovisku: Ano, UTF-16 by měl být považován za škodlivou odpověď.

    Jedna malá oprava:

    Aby se zabránilo tomu, že někdo omylem předá UTF-8 char* do ANSI-string verze funkcí Windows-API, měl by definujte UNICODE, ne _UNICODE. _UNICODE mapuje funkce jako _tcslen na wcslen, nikoli MessageBoxMessageBoxW. Místo toho se o to postará UNICODE definice. Důkaz je z hlavičky WinUser.h MS Visual Studio 2005:

    #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE 

    Minimálně tato chyba by měla být opravena na utf8everywhere.org.

    Návrh:

    Možná by příručka měla obsahovat příklad explicitního použití širokoúhlého řetězcová verze datové struktury, aby bylo méně snadné ji zapomenout / zapomenout.Použití verzí datových struktur s širokým řetězcem nad rámec použití verzí funkcí s širokým řetězcem je ještě méně pravděpodobné, že jeden omylem zavolá verzi takové funkce s řetězcem ANSI.

    Příklad příkladu:

    WIN32_FIND_DATAW data; // Note the W at the end. HANDLE hSearch = FindFirstFileW(widen("*.txt").c_str(), &data); if (hSearch != INVALID_HANDLE_VALUE) { FindClose(hSearch); MessageBoxW(nullptr, data.cFileName, nullptr, MB_OK); } 

    Komentáře

    • dohodnuto; dík! Dokument budeme aktualizovat. Dokument stále potřebuje další vývoj a přidávání informací o databázích. Jsme rádi, že dostáváme příspěvky ve znění.
    • @PavelRadzivilovsky _UNICODE stále existuje 🙁
    • děkuji za připomenutí. Cubus, Jelle, Chcete uživatele do našeho SVN?
    • @Pavel Jistě, ocenili byste to!
    • @JelleGeerts: Omlouvám se za toto zpoždění. Vždy nás můžete kontaktovat prostřednictvím našich e-mailů (propojených z manifestu) nebo Facebooku. Snadno nás najdete. I když věřím, že jsme vyřešili problém, který jste sem přinesli (a připsal jsem vám ho tam), celá debata UTF-8 vs UTF-16 je stále relevantní. Pokud máte více přispějte, neváhejte nás kontaktovat prostřednictvím těchto soukromých kanálů.

    Odpověď

    Někdo řekl, že UCS4 a UTF-32 byly totéž. Ne, ale vím, co tím myslíš. Jedním z nich je kódování toho druhého. Přál bych si, aby „od prvního napadlo specifikovat endianismus, takže bychom zde také nemohli bojovat o endianessskou bitvu. Nemohli to vidět přicházet? Alespoň UTF-8 je všude stejný re (pokud někdo nesleduje původní specifikaci se 6 bajty).

    Pokud používáte UTF-16, musíte zahrnout zpracování vícebajtových znaků. Nemůžete „jít na N-tý znak indexováním 2N do bajtového pole. Musíte to projít, nebo mít indexy znaků. Jinak jste napsali chybu.

    Aktuální návrh specifikace C ++ říká že UTF-32 a UTF-16 mohou mít varianty s malým endianem, big-endianem a nespecifikované varianty. Opravdu? Pokud by Unicode určil, že každý musí od začátku dělat malý endian, bylo by to všechno jednodušší. (Byl bych také v pořádku s big-endianem.) Místo toho to někteří lidé implementovali jedním způsobem, někteří jiným, a teď jsme „zaseknutí hloupostí pro nic za nic. Někdy je trapné být softwarovým inženýrem.

    Komentáře

    • Nespecifikovaná endianess by měla obsahovat BOM jako první znak, který se používá k určení, jakým způsobem má být řetězec přečten. UCS-4 a UTF-32 jsou dnes opravdu stejné, tj. Číselná hodnota UCS mezi 0 a 0x10FFFF uložená v 32bitovém celém čísle.
    • @Tronic: Technicky to není pravda. Přestože UCS-4 může ukládat jakékoli 32bitové celé číslo, UTF-32 má zakázáno ukládat znaky bez znaku, které jsou pro výměnu nelegální, například 0xFFFF, 0xFFFE a všechny náhradní. UTF je transportní kódování, nikoli interní.
    • Problémy endianness jsou nevyhnutelné, pokud různé procesory nadále používají různé bajtové objednávky. Mohlo by však být hezké, kdyby existovalo " upřednostňované " bajtové pořadí pro ukládání souborů UTF-16.
    • I když má UTF-32 pevnou šířku pro body kódu , není pevnou šířkou pro znaky . (Slyšeli jste něco, co se nazývá " kombinující znaky "?) Takže nemůžete ' jít na N ' th znak jednoduše indexováním 4N do bajtového pole.

    Odpověď

    Nemyslím si, že je to na škodu, pokud je vývojář dostatečně opatrný.
    A pokud to dobře vědí, měli by tento kompromis přijmout.

    Jako japonskému vývojáři softwaru považuji UCS-2 za dostatečně velký a omezení prostoru zjevně zjednodušuje logiku a snižuje runtime paměť, takže použití utf-16 pod omezením UCS-2 je dost dobré.

    Existuje souborový systém nebo jiná aplikace, která předpokládá, že kódy a bajty jsou proporcionální, takže je možné zaručit, že nezpracované číslo kódového bodu bude vhodné pro určité úložiště pevné velikosti.

    Jedním příkladem je NTFS a VFAT se specifikací UCS-2 jako kódování úložiště jejich názvů souborů.

    Pokud se tento příklad opravdu chce rozšířit o podporu UCS-4, mohl bych souhlasit s použitím utf-8 pro všechno, ale pevná délka má dobré body jako:

    1. může zaručit velikost podle délky (velikost dat a délka kódového bodu je proporcionální)
    2. může použít kódovací číslo pro vyhledávání hash
    3. nekomprimovaná data mají přiměřenou velikost (ve srovnání s utf-32 / UCS-4)

    V budoucnu, kdy bude paměť / výpočetní výkon levný i v jakýchkoli vložených zařízeních, můžeme akceptovat, že zařízení bude trochu pomalé kvůli dalším chybám mezipaměti nebo chybám stránek a další paměti použití, ale to se v blízké budoucnosti pravděpodobně nestane …

    Komentáře

    • Pro ty, kdo čtou tento komentář, stojí za zmínku, že UCS- 2 není totéž jako UTF-16. Pro pochopení vyhledejte rozdíly.

    Odpověď

    „Měl by být jeden z nejpopulárnějších kódování UTF-16 považována za škodlivá? „

    Je to docela možné, ale alternativy by neměly být nutně považovány za mnohem lepší.

    Základní problém spočívá v tom, že existuje mnoho různých pojmů: glyfy, znaky, kódové body a sekvence bajtů. Mapování mezi každým z nich je netriviální, a to i za pomoci normalizační knihovny. (Například některé znaky v evropských jazycích, které jsou psány skriptem založeným na latince, nejsou psány jediným kódovým bodem Unicode. A to je na jednodušším konci složitosti!) To znamená, že získat vše správné je docela překvapivě obtížné; lze očekávat bizarní chyby (a místo toho, abyste o nich jen sténali, řekněte správcům příslušného softwaru).

    Jediný způsob, jak UTF- 16 lze považovat za škodlivý na rozdíl od UTF-8, řekněme, že má jiný způsob kódování kódových bodů mimo BMP (jako dvojice náhradníků). Pokud si kód přeje získat přístup nebo iterovat podle kódového bodu, to znamená, že si musí být toho rozdílu vědom. OTOH, znamená to, že podstatná část existujícího kódu, která předpokládá „znaky“, se vždy vejde do dvoubajtové veličiny – docela běžný, i když nesprávný předpoklad – může na přinejmenším pokračujte v práci, aniž byste to všechno přestavovali. Jinými slovy, alespoň se uvidíte tyto postavy s tím není správně zacházeno!

    Obrátím vaši otázku na hlavu a řeknu, že celý ten zatracený shebang Unicode by měl být považován za škodlivý a každý by měl používat 8bitové kódování, kromě Viděl jsem (za posledních 20 let), kam to vede: strašný zmatek ohledně různých kódování ISO 8859, plus celá sada těch používaných pro azbuku, a sada EBCDIC, a … no, Unicode pro všechny své chyby překonává to . Kéž by to nebyl „ošklivý kompromis mezi různými zeměmi“ nedorozumění.

    Komentáře

    • S vědomím svého štěstí jsme za pár let ' V UTF-16 nám dojde místo. Meh.
    • Základní otázkou je, že text je klamně tvrdý. Žádný přístup k reprezentaci těchto informací digitálním způsobem nemůže být nekomplikovaný. ' má stejný důvod, že data jsou tvrdá, kalendáře jsou obtížné, čas je obtížný, osobní jména jsou tvrdá, poštovní adresy jsou tvrdé: kdykoli se digitální stroje protínají s lidskými kulturními konstrukty, složitost vybuchne. Je to fakt života. Lidé nefungují na digitální logice.

    Napsat komentář

    Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *