Domanda

Una cosa che non ho mai veramente capito è il concetto di codifica dei caratteri. Il modo in cui la codifica viene gestita in memoria e il codice spesso mi confonde nel fatto che copio un esempio da Internet senza capire veramente cosa fa. Sento che è un argomento molto importante e molto trascurato che più persone dovrebbero prendersi il tempo per ottenere il giusto (incluso me stesso).

Sto cercando delle buone risorse, al punto, per apprendere i diversi tipi di codifica e conversione dei caratteri (preferibilmente in C #). Sia i libri che le risorse online sono i benvenuti.

Grazie.


Modifica 1:

Grazie per le risposte finora. In particolare, sto cercando ulteriori informazioni sul modo in cui .NET gestisce la codifica. So che può sembrare vago ma non so davvero cosa chiedere. Immagino di essere curioso di sapere come viene rappresentata la codifica in una classe di stringhe C # e se la classe stessa può gestire diversi tipi di codifica o ci sono classi separate per questo?

È stato utile?

Soluzione

Comincerei con questa domanda: che cos'è un personaggio?

  • L'identità logica: un punto di codice . Unicode assegna un numero a ciascun carattere che non è necessariamente correlato a nessun modulo bit / byte. Le codifiche (come UTF-8) definiscono il mapping ai valori byte.
  • Bit e byte: il modulo codificato . Uno o più byte per punto di codice, valori determinati dalla codifica utilizzata.
  • Cosa vedi sullo schermo: un grapheme . Il grapheme è creato da uno o più punti di codice. Queste sono le cose alla fine della presentazione.

Questo codice trasforma in.txt da windows-1252 a UTF-8 e lo salva come out.txt.

using System;
using System.IO;
using System.Text;
public class Enc {
  public static void Main(String[] args) {
    Encoding win1252 = Encoding.GetEncoding(1252);
    Encoding utf8 = Encoding.UTF8;
    using(StreamReader reader = new StreamReader("in.txt", win1252)) {
      using(StreamWriter writer = new StreamWriter("out.txt", false, utf8)) {
        char[] buffer = new char[1024];
        while(reader.Peek() > 0) {
          int r = reader.Read(buffer, 0, buffer.Length);
          writer.Write(buffer, 0, r); 
        }
      }
    }
  }
}

Qui avvengono due trasformazioni. Innanzitutto, i byte vengono decodificati da UTF-16 a char (little endian, penso) nel buffer <=>. Quindi il buffer viene trasformato in <=>.

Codepoints

Alcuni punti di codice di esempio:

  • U + 0041 è LATINA DI CAPITALE LATINA A (A)
  • U + 00A3 è POUND SIGN (& # 163;)
  • U + 042F è LETTERA DI CAPITALE CILILLICO YA (& # 1071;)
  • U + 1D50A è MATEMATICA FRAKTUR CAPITAL G (& # 120074;)

Codifica

Ovunque lavori con i personaggi, sarà in una codifica di qualche forma. C # utilizza UTF-16 per il suo tipo di carattere , che definisce larga 16 bit.

Puoi pensare a una codifica come una mappatura tabulare tra punti di codice e rappresentazioni di byte.

CODEPOINT       UTF-16BE        UTF-8     WINDOWS-1252
U+0041 (A)         00 41           41               41
U+00A3 (£)         00 A3        C2 A3               A3
U+042F (Ya)        04 2F        D0 AF                -
U+1D50A      D8 35 DD 0A  F0 9D 94 8A                -

La System.Text.Encoding espone tipi / metodi per eseguire le trasformazioni.

Grafemi

Il grafema che vedi sullo schermo può essere costruito da più di un punto di codice. Il carattere e-acuto (e & # 769;) può essere rappresentato con due punti di codice, LETTER SMALL LETTER E U + 0065 e COMBINING ACUTE ACCENT U + 0301.

('& # 233;' è più comunemente rappresentato dal singolo punto di codice U + 00E9. Puoi passare da uno all'altro usando la normalizzazione. Tuttavia, non tutte le sequenze di combinazione hanno un singolo carattere equivalente.)

Conclusioni

  • Quando codifichi una stringa C # in una codifica, stai eseguendo una trasformazione da UTF-16 a quella codifica.
  • La codifica può essere una trasformazione con perdita di dati: la maggior parte delle codifiche non Unicode può codificare solo un sottoinsieme di caratteri esistenti.
  • Poiché non tutti i punti di codice possono rientrare in un singolo carattere C #, il numero di caratteri nella stringa può essere maggiore del numero di punti di codice e il numero di punti di codice può essere maggiore del numero di grafi renderizzati.
  • Il " lunghezza " di una stringa è sensibile al contesto, quindi devi sapere quale significato stai applicando e utilizzare l'algoritmo appropriato. Il modo in cui questo viene gestito è definito dal linguaggio di programmazione che stai utilizzando.
  • Dare ai caratteri Latin-1 valori identici in molte codifiche dà ad alcune persone delusioni di ASCII.

(Questo è un po 'più lungo di quanto pensassi, e probabilmente più di quello che volevi, quindi mi fermerò. Ho scritto un ancora più lungo pubblica qui la codifica Java .)

Altri suggerimenti

Wikipedia ha una spiegazione abbastanza buona della codifica dei caratteri in generale: http://en.wikipedia.org / wiki / Character_encoding .

Se stai cercando i dettagli di UTF-8, che è una delle codifiche di personaggi più popolari, dovresti leggere UTF-8 e domande frequenti su Unicode .

E, come già sottolineato, " The Absolute Minimum Every Software Developer Assolutamente, assolutamente da sapere sugli Unicode e sui set di caratteri (No Excuses!) & Quot; è un ottimo tutorial per principianti.

C'è il famoso articolo di Joel " Il minimo assoluto che ogni sviluppatore di software deve assolutamente conoscere positivamente su Unicode e set di caratteri (senza scuse!) " http://www.joelonsoftware.com/articles/Unicode.html

Modifica: anche se si tratta più di formati di testo, sulla rilettura credo che tu sia più interessato a cose come la codifica HTML e la codifica URL? Quali sono per sfuggire a caratteri speciali che hanno significati significativi all'interno di html o urls (es. & Lt; e & Gt; in html, o? E = in urls)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top