Perché ci sono più codifiche Unicode?


41

Ho pensato che Unicode fosse progettato per aggirare l'intero problema di avere molte codifiche diverse a causa di un piccolo spazio di indirizzi (8 bit) nella maggior parte dei tentativi precedenti (ASCII, ecc.).

Perché allora ci sono così tante codifiche Unicode? Anche più versioni di (essenzialmente) la stessa, come UTF-8, UTF-16, ecc.


11
UTF-8 non è uguale a UTF-16. L'elenco crescerà non appena incontreremo altri sistemi solari con pianeti simili alla terra.
setzamora,

1
@Joset: abbiamo già Klingon. Abbiamo la maggior parte dei linguaggi terrestri sul BMP con leggera fuoriuscita in pianure 1,2. Se le attuali correnti sono corrette e ci sono solo 42 specie senzienti nella galassia che raggiungono un punto in cui possono usare il viaggio nello spazio (quindi consentire il primo contatto), dovremmo essere in grado di spremere tutti i caratteri in tutte le lingue in UNICODE (supponendo che possiamo espandere da 21 a 22 bit per consentire 64 pianure). Ciò lascia anche 10 bit di spazio di buffer se vogliamo includere le specie primitive che non hanno raggiunto il volo spaziale.
Martin York,

7
@Kevin Hsu: UTF-7,8,16LE, 16BE, 32LE, 32BE. Quindi, esistono almeno 6 codifiche reali. UTF-9 e UTF-18 sono pesce d'aprile.
MSalters,

9
La cosa buona degli standard è che ce ne sono così tanti
Homde,

1
Scopri cosa ha detto Spolsky su Unicode e sulla codifica .
MPelletier,

Risposte:


29

Perché le persone non vogliono spendere 21 bit per ogni personaggio. Su tutti i sistemi moderni, ciò significherebbe essenzialmente usare tre byte per carattere, che è tre volte più di quello a cui erano abituate le persone, quindi non erano disposti ad adottare Unicode. È stato necessario trovare un compromesso: ad esempio UTF-8 è ottimo per il testo inglese perché i file ASCII legacy non devono essere convertiti affatto, ma è meno utile per le lingue europee e di scarsa utilità per le lingue asiatiche.

Quindi, in sostanza, sì, avremmo potuto definire una singola codifica universale e una singola tabella di caratteri universali, ma il mercato non l'avrebbe accettata.


8
+1 Ottima risposta. Ad essere sincero, è l'unico che risponde davvero a questa domanda. Tutte le altre risposte sono (più o meno) su come i byte sono disposti in tutte le diverse codifiche Unicode.
Jacek Prucia,

Storicamente è una semplice questione di disaccordo. Tuttavia, oggi non vedo molto altro che UTF-8, mentre ci sono scenari teorici in cui UTF-16 consumerebbe meno spazio, non è un grande margine e sono rari. Il posto più importante in cui si vorrebbe risparmiare spazio è per i siti Web, ma sono pieni di codici HTML che sono di gran lunga più brevi usando UTF-8. Ad esempio, potresti utilizzare Shift JISun sito Web giapponese più piccolo dell'equivalente UTF-8, ma funziona solo perché è un set di caratteri specifico per il giapponese.
aaaaaaaaaaaa

2
Nemmeno vero. Poiché i formati compressi sono realmente utilizzati solo per il trasporto e lo stoccaggio. All'interno di un'applicazione è più comunemente usare UCS-2 o UCS-4 poiché sono a larghezza fissa ma occupano 2 o 4 byte per carattere. Quindi le applicazioni sono disposte a rinunciare allo spazio per la facilità d'uso.
Martin York,

but it is less useful for European languages, and of little use for Asian languages- questo è solo sbagliato. Per "utilità" intendi la compressione? Bene, allora UTF-8 fornisce una migliore compressione per le lingue europee perché in ogni testo ci sono spazi e segni di punteggiatura che prendono solo un singolo byte.
Nick Volynkin,

37

Unicode è un carattere a 21 bit che codifica per descrivere in modo univoco "CodePoints" ogni punto di codice rappresentato da un glifo (una rappresentazione grafica).

  • 16 bit utilizzati per identificare un punto di codice in un piano (la maggior parte dei punti di codice si trova sul piano 0).
  • 5 bit per identificare il piano.

Le codifiche supportate sono:

  • UTF-8 (per codificare ciascun punto usando valori a 8 bit)
  • UTF-16 (per codificare ogni punto usando valori a 16 bit)
  • UTF-32 (per codificare ogni punto usando valori a 32 bit)

Ma non importa quale sia la codifica quando decodifichi tutti mappano indietro a un punto di codice specifico che ha lo stesso significato (motivo per cui è bello).

UTF-8

Questo è un formato di dimensioni variabili. Dove ogni punto di codice è rappresentato da 1 a 4 byte.

UTF-16

Questo è un formato di dimensioni variabili. I punti di codice sul "Piano multilingue di base" (BMP o Piano 0) possono essere rappresentati da 1 singolo valore a 16 bit. I punti di codice su altri piani sono rappresentati da una coppia surrogata (2 valori a 16 bit).

UTF-32

Questo è un formato a dimensione fissa. Tutti i punti di codice sono rappresentati da un singolo valore a 32 bit.


2
Mi piace anche questa risposta. Ne scrivevo uno simile, ma questo è chiaro. Aggiungo anche che UTF-8 è utile anche in quanto le stringhe ASCII sono automaticamente UTF-8.
Kevin Hsu,

4
Per favore, è il piano multilingue di base , non un piano .
JSB ձոգչ

3
Questa è una buona risposta, ma penso che permetta ancora la domanda "Perché?", Anche se questa risposta lo tocca implicitamente. Per elaborare: UTF-32 è un approccio più diretto (alcuni direbbero più semplice) di codifica dei caratteri Unicode, ma spreca anche molto spazio, poiché ogni personaggio occupa 4 byte. UTF-8 è molto più compatto e retrocompatibile con ASCII, ma non è regolare: un personaggio può impiegare da 1 a 4 byte per codificare, il che rende più difficile il suo lavoro. UTF-16 è una sorta di approccio ibrido tra i due, principalmente con i pro ei contro di ciascuno.
mipadi,

4
C'è un compromesso tra l'utilizzo della memoria (dove UTF-8 è il migliore, poiché i caratteri più comuni sono a byte singolo) e la velocità di elaborazione (dove UTF-32 è il migliore, perché tutti i caratteri hanno le stesse dimensioni, consentendo determinate ottimizzazioni e dando perfetto Allineamento a 32 bit in memoria). Di conseguenza, i protocolli di rete e i formati di file utilizzano comunemente UTF-8 (per risparmiare larghezza di banda / spazio di archiviazione), mentre gli interpreti di script e il tempo di esecuzione della lingua possono preferire UTF-16 o UTF-32.
tdammers,

2
@Marcel: Un "CodePoint" è un "CodePoint" non un character(poiché un carattere può essere costruito da più "CodePoints"). Non confondere i due termini. Ma hai ragionevolmente "CodePoints" non si riferiscono a glifi. Un Glifo è solo una rappresentazione grafica di un punto di codice. Una differenza sottile ma importante.
Martin York,

25

Penso che sia utile separare le 2 idee:

  1. Unicode - mappatura di caratteri provenienti da tutto il mondo per codificare punti.
  2. Codifica: mappatura di punti di codice su schemi di bit (UTF-8, UTF-16, ecc.).

UTF-8, UTF-16 e altre codifiche ha i propri vantaggi e svantaggi. Meglio consultare Wikipedia a riguardo.


@jfs: Perché mai avere Unicode se c'è ancora una dozzina o più codifiche diverse che sono comunque tutte diverse sul filo? A che serve avere una mappatura globale in sé e per sé?
Matthew Scharley,

10
@Matthew Scharley: La stai guardando male. UNICODE mappa tutti i caratteri di tutte le lingue (incluso Klingon) su un ID UNICO (punto di codice). Le codifiche sono semplicemente un modo per comprimere i punti di codice su disco o un flusso attraverso una rete. UTF sta per "formato di trasporto UNICODE". Si dovrebbe sempre considerare un punto di codice UNICODE come un valore di 21 bit. Il vantaggio rispetto ad altri formati è che tutti i caratteri sono identificati in modo univoco e non si sovrappongono (a differenza di Latin-1, Latin-2 ecc.).
Martin York,

@Matthew Scharley Perché avere una mappatura globale? In realtà ognuno aveva la propria mappatura in passato (ricordi le pagine di codice?). Penso che un esempio sciocco chiarirà le cose. Immagina l'idea dell'amore. Come lo rappresenterai per qualcuno? Dare fiori? Dire ti amo"? Ognuno ha il suo modo di esprimerlo. L'amore (che è un'idea astratta) è come i punti del codice. Esprimerlo è come le codifiche. :)
jfs,

4
Unicode è l'alfabeto globale. UTF-x è il modo in cui viene trasportato dai computer, poiché è difficile far passare la carta attraverso i fili.
Mel,

1
@Martin, Klingon in realtà non ce l'ha fatta. Né il Tengwar o Cirith, usato per scrivere le lingue elfiche di Tolkein.
TRiG

9

UTF-7, UTF-8, UTF-16 e UTF-32 sono semplicemente formati di trasformazione algoritmica della stessa codifica (codepoints) di caratteri. Sono codifiche di un sistema di codificazione dei caratteri.

Sono inoltre algoritmicamente più facili da navigare avanti e indietro rispetto alla maggior parte degli schemi precedenti per gestire set di caratteri di dimensioni superiori a 256 caratteri.

Questo è molto diverso dalla codifica dei glifi generalmente specifica per paese e talvolta specifica per il fornitore. Solo nel giapponese, ci sono state molte variazioni di JIS da solo, per non parlare dell'EUC-JP e della trasformazione orientata alla codepage di JIS che le macchine DOS / Windows usavano chiamata Shift-JIS. (In una certa misura, ci sono state trasformazioni algoritmiche di queste, ma non erano particolarmente semplici e c'erano differenze specifiche nei fornitori disponibili per i caratteri. Moltiplicalo per duecento paesi e l'evoluzione graduale di sistemi di font più sofisticati (post greenscreen era), e hai avuto un vero incubo.

Perché dovresti aver bisogno di queste forme di trasformazione di Unicode? Poiché molti sistemi legacy presupponevano sequenze di caratteri a 7 bit dell'intervallo ASCII, quindi era necessaria una soluzione pulita a 7 bit che passasse in modo sicuro i dati non corrotti attraverso tali sistemi, quindi era necessario UTF-7. Quindi c'erano sistemi più moderni in grado di gestire set di caratteri a 8 bit, ma i null generalmente avevano significati speciali per loro, quindi UTF-16 non funzionava per loro. 2 byte potevano codificare l'intero piano multilingue di base di Unicode nella sua prima incarnazione, quindi UCS-2 sembrava un approccio ragionevole per i sistemi che sarebbero stati "Unicode consapevoli da zero" (come Windows NT e Java VM); quindi le estensioni oltre quella necessitavano di caratteri aggiuntivi, che ha portato alla trasformazione algoritmica delle codifiche di 21 bit riservate dallo standard Unicode e sono nate coppie surrogate; che necessitava di UTF-16. Se avevi qualche applicazione in cui la coerenza della larghezza dei caratteri era più importante dell'efficienza della memoria, UTF-32 (una volta chiamata UCS-4) era un'opzione.

UTF-16 è l'unica cosa che è lontanamente complessa da gestire, e che è facilmente mitigata dalla piccola gamma di caratteri che sono interessati da questa trasformazione e dal fatto che le sequenze di piombo a 16 bit sono ordinatamente in una gamma completamente distinta dal finale Sequenze a 16 bit. È anche più semplice dei mondi che cercare di avanzare e retrocedere in molte prime codifiche dell'Asia orientale, dove avevi bisogno di una macchina statale (JIS ed EUC) per gestire le sequenze di fuga, o potenzialmente di spostare indietro di diversi personaggi fino a quando non hai trovato qualcosa che era garantito essere solo un byte iniziale (Shift-JIS). UTF-16 aveva alcuni vantaggi su sistemi che potevano anche eseguire in modo efficiente sequenze a 16 bit.

A meno che tu non debba sopravvivere a dozzine (centinaia, in realtà) di codifiche diverse, o costruire sistemi che supportano più lingue in codifiche diverse a volte anche nello stesso documento (come WorldScript nelle versioni precedenti di MacOs), potresti pensare dei formati di trasformazione unicode come complessità non necessaria. Ma è una drastica riduzione della complessità rispetto alle alternative precedenti e ogni formato risolve un vero vincolo tecnico. Sono inoltre convertibili in modo efficiente tra loro, senza richiedere tabelle di ricerca complesse.


1
Le varie macchine statali JIS ed EUC sono davvero brutte, e doppiamente se stai lavorando per trasformarti tra loro. Unicode semplifica enormemente questo. L'unico problema principale con Unicode è che hai avuto di smettere di pensare di byte come caratteri, è ASCII-utilizzando piccoli caratteri-tarati sciovinista voi!
Donal Fellows,

6

Unicode non è stato progettato per aggirare l'intero problema di avere molte codifiche diverse.

Unicode è stato progettato per aggirare l'intero numero di un numero che rappresenta molte cose diverse a seconda della tabella codici in uso. I numeri 0 - 127 rappresentano gli stessi caratteri in qualsiasi tabella codici Ansi. Questo è anche noto come grafico ASCII o set di caratteri. Nelle pagine codici Ansi, che consentono 256 caratteri, i numeri 128 - 255 rappresentano caratteri diversi in pagine codici diverse.

Per esempio

  • Il numero $ 57 rappresenta una W maiuscola in tutte le pagine di codice, ma
  • Il numero $ EC rappresenta il simbolo di inifinità nella tabella codici 437 (US), ma una "LETTERA LATINA PICCOLA N CON CEDILLA" nella tabella codici 775 (Baltico)
  • Il segno Cent è il numero $ 9 miliardi nella tabella codici 437, ma il numero 96 nella tabella codici 775

Quello che ha fatto Unicode è stato capovolgerlo. In Unicode non c'è "riutilizzo". Ogni numero rappresenta un singolo carattere unico. Il numero $ 00A2 in Unicode è il segno di centesimo e il segno di centesimo non appare da nessun'altra parte nella definizione Unicode.

Perché allora ci sono così tante codifiche Unicode? Anche più versioni di (essenzialmente) la stessa, come UTF-8, UTF-16, ecc.

Non ci sono più versioni della stessa codifica. Esistono più codifiche della stessa mappa di definizione dei caratteri Unicode e queste sono state "inventate" per amministrare i requisiti di archiviazione per usi diversi dei vari piani linguali esistenti in Unicode.

Unicode definisce (o ha lo spazio per definire) 4.294.967.295 caratteri univoci. Se si desidera mapparli alla memoria su disco / memoria senza effettuare conversioni algoritmiche, sono necessari 4 byte per carattere. Se hai bisogno di memorizzare testi con caratteri di tutti i piani linguali, allora UTF-32 (che è fondamentalmente un semplice carattere 1 - codifica di archiviazione a 4 byte della definizione unicode) è probabilmente quello che ti serve.

Ma quasi nessun testo usa caratteri di tutti i piani linguali. E poi usare 4 byte per personaggio sembra un grande spreco. Soprattutto quando si tiene conto del fatto che la maggior parte delle lingue sulla terra sono definite all'interno del cosiddetto piano multilingue di base (BMP): i primi 65536 numeri della definizione Unicode.

Ed è qui che è entrato UTF-16. Se usi solo caratteri del BMP, UTF-16 lo memorizzerà in modo molto efficiente usando solo due byte per carattere. Utilizzerà solo più byte per i caratteri al di fuori del BMP. La distinzione tra UTF-16LE (Little Endian) e UTF-16BE (Big Endian) ha davvero a che fare con il modo in cui i numeri sono rappresentati nella memoria del computer (modello di byte che A0significa hex $ A0 o $ 0A).

Se il tuo testo usa ancora meno caratteri diversi, come la maggior parte dei testi nelle lingue dell'Europa occidentale, vorrai limitare ancora di più i requisiti di archiviazione per i tuoi testi. Da qui UTF-8, che utilizza un singolo byte per memorizzare i caratteri presenti nel grafico ASCII (i primi 128 numeri) e una selezione dai caratteri Ansi (i secondi 128 numeri delle varie tabelle codici). Utilizzerà solo più byte per i caratteri al di fuori di questo set di "caratteri più utilizzati".

Quindi, per ricapitolare:

  • Unicode è una mappatura dei personaggi in tutte le lingue sulla terra (e alcuni Klingon per l'avvio) e poi alcuni (matematici, musicali, ecc.) Su un numero univoco.
  • Le codifiche sono algoritmi definiti per memorizzare i testi utilizzando i numeri di questa mappa di caratteri univoca nel modo più efficiente possibile, dato l '"utilizzo medio" dei caratteri all'interno dei testi.

2
"I numeri 0 - 127 rappresentano gli stessi caratteri in qualsiasi tabella codici." - beh, a meno che tu non stia parlando di EBCDIC, nel qual caso $57non è un W
MSalters

@MSalters: hai assolutamente ragione. EBCDIC è diverso (e ce ne sono altri EBCDIC). Immagino che i miei giorni da mainframe siano così a lungo alle mie spalle che non mi sono ricordato, o ho represso questi ricordi troppo duramente e troppo a lungo ... :-)
Marjan Venema,

"I numeri 0 - 127 rappresentano gli stessi caratteri in qualsiasi tabella codici." In realtà ci sono codifiche, come BinarySignWriting, che non sono superset di ASCII. BinarySignWriting, infatti, non include alcun carattere ASCII.
TRiG

@TRiG: Ecco perché ho modificato la mia dichiarazione in modo specifico sulle pagine di codice Ansi. Devo averlo fatto prima di rinfrescarti ...
Marjan Venema,

Sì. C'è stato un commento extra e un aggiornamento post fatto mentre stavo scrivendo il mio commento. Tuttavia, BinarySignWriting è interessante.
TRiG

2

Unicode definisce la mappa tra numeri e caratteri. Tuttavia, quando si invia un numero a un destinatario, è comunque necessario definire come rappresentare quel numero. Ecco a cosa serve UTF. Definisce come rappresentare un numero in un flusso di byte.


2

La logica alla base di UTF-32 è semplice: è la rappresentazione più semplice dei punti di codice Unicode. Quindi perché non è tutto in UTF-32? Due ragioni principali:

Uno è di dimensioni . UTF-32 richiede 4 byte per ogni carattere. Per il testo che utilizza solo caratteri nella posizione multilingue di base, questo è il doppio dello spazio rispetto a UTF-16. Per il testo inglese, è 4 volte più spazio di US-ASCII.

Il motivo principale è la compatibilità con le versioni precedenti . Ogni codifica Unicode diversa dall'UTF-32 "non codificato" è stata progettata per la compatibilità all'indietro con uno standard precedente.

  • UTF-8: compatibilità all'indietro con US-ASCII.
  • UTF-16: compatibilità all'indietro con UCS-2 (Unicode a 16 bit prima che fosse espanso oltre il BMP).
  • UTF-7: compatibilità all'indietro con server di posta non puliti a 8 bit.
  • GB18030: compatibilità all'indietro con le codifiche GB2312 e GBK per il cinese.
  • UTF-EBCDIC: compatibilità all'indietro con il sottoinsieme latino di base di EBCDIC.

Ho pensato che Unicode fosse progettato per aggirare l'intero problema di avere molte codifiche diverse

Lo era e lo ha fatto. È molto più facile convertire tra UTF-8, -16 e -32 che gestire il vecchio sistema di centinaia di codifiche di caratteri diverse per lingue e sistemi operativi diversi.


1

Sai che un file zip può comprimere un file in modo che sia molto più piccolo (specialmente testo) e quindi decomprimerlo in una copia identica del file originale.

L'algoritmo zippato in realtà ha diversi algoritmi con diverse caratteristiche tra cui scegliere: memorizzato (nessuna compressione), Ridotto, Ridotto (metodi 1-4), Imploded, Tokenizing, Deflated, Deflate64, BZIP2, LZMA (EFS), WavPack, PPMd, dove teoricamente potrebbe provarli tutti e scegliere il risultato migliore, ma di solito basta andare con Deflated.

UTF funziona più o meno allo stesso modo. Esistono diversi algoritmi di codifica ciascuno con caratteristiche diverse, ma di solito scegli UTF-8 perché è ampiamente supportato rispetto alle altre varianti UTF, che a sua volta è perché è bitally compatibile con ASCII a 7 bit che lo rende facile da utilizzare sulla maggior parte delle piattaforme di computer moderne che di solito utilizzano un'estensione a 8 bit di ASCII.


ørn: La differenza con un file zip è che c'è un'intestazione che ti dice quale compressione è attiva. Con i file di testo, dobbiamo ancora indovinare vero?
Matthew Scharley,

C'è una sequenza speciale che dice esattamente questo. A causa della retrocompatibilità con ASCII è facoltativo.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.