txt - theory and practice of text encoding

38
TXT Theory and practice of text encoding Michiel van Oosterhout July 2014

Upload: michielvoo

Post on 23-Jan-2018

194 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: TXT - Theory and practice of text encoding

TXT

Theory and practice of text encoding

Michiel van Oosterhout

July 2014

Page 2: TXT - Theory and practice of text encoding

Topics

Introduction

Definitions

Character sets

Unicode

Text encoding in C#

Unicode normalization

Summary

2

Page 3: TXT - Theory and practice of text encoding

INTRODUCTION

3

Page 4: TXT - Theory and practice of text encoding

Text processing: a domain model

4

Bytes

• Files

• Database

• Socket

• Stream

Text data

• string

• char

• Reader

• Writer

Text

• Visual

• Spoken

Program

Page 5: TXT - Theory and practice of text encoding

5

Page 6: TXT - Theory and practice of text encoding

DEFINITIONS

6

Page 7: TXT - Theory and practice of text encoding

★ Grapheme

Grapheme is the smallest written unit

– Letter from an alphabet: ⟨p⟩ or ⟨ß⟩ or ⟨â⟩ or ⟨π⟩

– Numerical digit: ⟨4⟩ or ⟨٤⟩ or ⟨Ⅲ⟩

– Punctuation: ⟨?⟩ or ⟨;⟩

– Ligatures: ⟨fi⟩ or ⟨&⟩

– Symbols: ⟨€⟩ or ⟨∞⟩

– CJK characters and ideographs: ⟨平⟩ or ⟨不⟩

7

Page 8: TXT - Theory and practice of text encoding

★ Diacritic

A mark that is added to a letter

Diacritical mark can take many forms, for example:

– Accent circumflex: ◌ as in ⟨â⟩

– Slash: ◌ as in ⟨ø⟩

– Cedilla: ◌ as in ⟨ç⟩

8

Page 9: TXT - Theory and practice of text encoding

★ Glyph

Visual representation of a grapheme or diacritic

Implemented strictly in the rendering of text

9

gg

Page 10: TXT - Theory and practice of text encoding

★ Control character

Used to embed instructions in text, for example:

– ␀ NULL

– ␄ end of transmission

– ␉ horizontal tab

10

Page 11: TXT - Theory and practice of text encoding

★ Abstract character

A unit of information used for the organization, control, or representation of textual data

Graphemes

Diacritical marks

Control characters

Miscellaneous characters…

Named

– LATIN CAPITAL LETTER Z

– HORIZONTAL ELLIPSIS

– EURO SIGN

Properties

– Is capital, is digit, is punctuation, …

11

Page 12: TXT - Theory and practice of text encoding

CHARACTER SETS

12

Page 13: TXT - Theory and practice of text encoding

★ Character set

A set of abstract characters

Each character has a corresponding numerical (uint) value, for example:

– A maps to 65

– B maps to 66

– a maps to 97

Also called:

– Code page

– Code table

– Character map

13

Page 14: TXT - Theory and practice of text encoding

★ Code points

A code point is an entry in the character table

Use hexadecimal notation for the numerical value

5A = Z = LATIN CAPITAL LETTER Z

14

Page 15: TXT - Theory and practice of text encoding

Some (Western European) character sets

ASCII (1963)– 128 code points (7-bit ★ code space)

– No accented letters

Windows-1252 (1985)

– 256 code points (8-bit code space)

– More symbols and accented letters

– Default in US/Western Europe Windows installations!

– Maps EURO SIGN to code point 80

– Incorrectly called ANSI

ISO-8859-1 (Latin 1, 1987) and ISO-8859-15 (Latin 9, 1999)– 256 code points (8-bit code space)

– Designed for Western European languages

– Latin 9 added EURO SIGN at A4

15

Page 16: TXT - Theory and practice of text encoding

UNICODE

16

Page 17: TXT - Theory and practice of text encoding

Character encoding scheme

A method of representing abstract characters in bytes

– A byte is defined as an octet (8 bits)

Many character sets have a simple encoding scheme

– Numerical value (code point) == byte value

Character sets with > 256 code points, require different encoding scheme

– CJK sets have several 1000 code points

– Unicode has > 110.000 code points

– Needs multiple bytes per code point

17

Page 18: TXT - Theory and practice of text encoding

Unicode

Standard for handling text in computing (since 1991)

Encodings

Character repertoire

– 21-bit code space

Rules

18

Page 19: TXT - Theory and practice of text encoding

Unicode 1.0 encoding scheme

16-bit code space

UCS-2

– 1 ★ code unit per code point

– 2 bytes per code unit

• Big endian (most significant byte of each byte pair at the lowest address/beginning)

– Can only encode U+0000 – U+FFFF

– EURO SIGN (U+20AC): [0x20 0xAC]

20

Page 20: TXT - Theory and practice of text encoding

Unicode 2.0 (1996)

21-bit code space

– Adds 16 new ★ planes

• Also 1 for private use

– Unicode 1.0 16-bit code space is now called ★ Basic Multilingual Plane (BMP)

21

Page 21: TXT - Theory and practice of text encoding

UCS-4 encoding scheme

Also called UTF-32

1 code unit per code point

4 bytes per code unit

– Choice of big endian (UTF-32BE) or little endian (UTF-32LE)

EURO SIGN (U+20AC): [0x00 0x00 0x20 0xAC] (big endian)

22

Page 22: TXT - Theory and practice of text encoding

UTF-16

1 or 2 code units per code point

– 2 code units are called a 'surrogate pair'

2 bytes per code unit

– Choice of big endian (UTF-16BE) or little endian (UTF-16LE)

Can encode U+0000 – U+10FFFF (17 planes)

EURO SIGN (U+20AC): [0x20 0xAC] (big endian)

GLOBE WITH MERIDIANS (U+1F310):

[0x3C 0xD8] [0x10 0xDF] (big endian)

• 1 code point > U+FFFF requires 2 code units

23

Page 23: TXT - Theory and practice of text encoding

UTF-8 encoding scheme

The ‘standard’ encoding scheme for the internet

Compatible with ASCII

1 – 4 code units per code point

1 byte per code unit

EURO SIGN (U+20AC): [0xE2] [0x82] [0xAC]

0- 7F: 0.......80– 7FF: 110..... 10......

800– FFFF: 1110.... 10...... 10......10000– 1FFFFF: 11110... 10...... 10...... 10......

24

Page 24: TXT - Theory and practice of text encoding

Byte Order Mark

ZERO-WIDTH NON-BREAK SPACE U+FEFF

Only used as the first character of an unmarked plaintext file

Indicator of endianness of UTF-16/32 encoding scheme

– Because these encoding schemes use 2 or 4 bytes per code unit

Signature for UTF-8 encoding scheme

– Does not indicate endianness, but rather the fact that the file is UTF-8 encoded

– Can cause problems (e.g. Linux/Unix scripts that must start with #!)

It is always preferable to 'tag' encoded text with the encoding scheme

– E.g. "this text is UTF-16BE (big endian)"

25

Page 25: TXT - Theory and practice of text encoding

TEXT ENCODING IN C#

26

Skip

Page 26: TXT - Theory and practice of text encoding

Encoding in C#

// Unicode literals (16-bit)var euro = "\u20AC";

// Unicode literal (32-bit)

var picto = "\U0001F310";

// Encode text to bytes

var bytes = Encoding.UTF8.GetBytes(euro);

> [0xE2, 0x82, 0xAC]

// Get a specific encoding scheme

var windows1252 = Encoding.GetEncoding("Windows-1252");

var bytes = windows1252.GetBytes(euro);

> [0x80]

27

Page 27: TXT - Theory and practice of text encoding

Decoding in C#

// Decode bytes

var bytes = new { 0xE2, 0x82, 0xAC };

var euro = Encoding.UTF8.GetString(bytes);

> €

// Decoding error

var windows1252 = Encoding.GetEncoding("Windows-1252");

var euro = windows1252.GetString(bytes);

> €

// To understand why, let's check the 'Windows-1252 bytes' for â

windows1252.GetBytes("â");

> [0xE2]

28

Page 28: TXT - Theory and practice of text encoding

Replacement fallback strategy in C#

// ASCII encoder will replace unknown characters with a '?'

var str = "€";

var bytes = Encoding.ASCII.GetBytes(str);

Encoding.ASCII.GetString(bytes);

> ?

// UTF-8 decoder will replace with REPLACEMENT CHARACTER U+FFFD

var str = "€";

var windows1252 = Encoding.GetEncoding("Windows-1252");

var bytes = windows1252.GetBytes(str);

Encoding.UTF8.GetString(bytes);

> �

29

Page 29: TXT - Theory and practice of text encoding

Code units in C#

// Strings are actually UTF-16!

var picto = "\U0001F310";

picto.Length;

> 2

// UTF-16 uses 2 code units to encode code points > 0xFFFF

// Using a char type (notice single quotes)

var picto = '\U0001F310';

Compiler error CS1012: Too many characters in character literal

// char type can only contain a single UTF-16 code unit,

// not a surrogate pair

30

Page 30: TXT - Theory and practice of text encoding

Code units in C#

// String with 2 abstract characters

// LATIN SMALL LETTER E and COMBINING ACUTE ACCENT

var str = "\u0065\u0301";

str.Length;

> 2

str[0];

> e

// Using System.Globalization.String.Info

var enumerator = String.Info.GetTextElementEnumerator(str);

enumerator.MoveNext();

enumerator.Current;

> e

31

Page 31: TXT - Theory and practice of text encoding

UNICODE NORMALIZATION

32

Skip

Page 32: TXT - Theory and practice of text encoding

Normalization: ★ canonical equivalence

Multiple (sequences of) code points representing the same character

LATIN SMALL LETTER A WITH CIRCUMFLEX (U+00E2)

– A single grapheme: ⟨â⟩

– A ★ 'primary composite'

– For compatibility with other character sets

– Similar to E2 in Windows-1252 or ISO-8859-1 (Latin 1)

LATIN SMALL LETTER A (U+0061) + COMBINING CIRCUMFLEX ACCENT

(U+0302)

– A single grapheme: ⟨a⟩, combined with a diacritic (not a grapheme): ◌

33

Page 33: TXT - Theory and practice of text encoding

Canonical equivalence in C# - 1/2

// Single character

var bytes = new byte[] { 0xC3, 0xA2 };

var str1 = Encoding.UTF8.GetString(bytes);

> â

str.Length;

> 1

// a (0x61) with combining diacritical mark (0xCC, 0x82)

bytes = new byte[] { 0x61, 0xCC, 0x82 };

var str2 = Encoding.UTF8.GetString(bytes);

str2;

> â

str2.Length;

> 2

34

Page 34: TXT - Theory and practice of text encoding

Canonical equivalence in C# - 2/2

str1.Length;

> 1

// Decompose into separate code points

str1.Normalize(NormalizationForm.FormD).Length;

> 2

str2.Length;

> 2

// Compose into 'primary composite' (the single character)

str2.Normalize(NormalizationForm.FormC).Length;

> 1

35

Page 35: TXT - Theory and practice of text encoding

Normalization: ★ compatibility

Multiple (sequences of) code points representing compatible characters

– Different appearance, same meaning

LATIN SMALL LIGATURE FF (U+FB00)

– A single grapheme: ⟨ff⟩

LATIN SMALL LETTER F (U+0046) + LATIN SMALL LETTER F (U+0046)

– Two graphemes: ⟨f⟩⟨f⟩

36

Page 36: TXT - Theory and practice of text encoding

Compatibility in C# - 2/2

// The ff ligature

var bytes = new byte[] { 0xEF, 0xAC, 0x80 };

var str1 = Encoding.UTF8.GetString(bytes);

str1.Length;

> 1

str2 = str.Normalize(NormalizationForm.FormKD);

str2.Length;

> 2

str2;

> ff

// ff was decomposed into two characters: ff

37

Page 37: TXT - Theory and practice of text encoding

SUMMARY

38

Page 38: TXT - Theory and practice of text encoding

Further reading

https://en.wikipedia.org/wiki/Unicode (Unicode on Wikipedia)

http://www.joelonsoftware.com/articles/Unicode.html (The Absolute Minimum)

http://www.objc.io/issue-9/unicode.html (NSString and Unicode)

http://www.unicode.org/glossary/ (Glossary of Unicode terms)

http://www.unicode.org/faq/ (Unicode FAQ)

http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt (UTF-8 history)

http://msdn.microsoft.com/en-us/library/ms404377(v=vs.110).aspx (Character Encoding in the .NET Framework)

http://www.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/ (All about Unicode)

http://www.tbray.org/ongoing/When/200x/2003/04/06/Unicode (On the Goodness of Unicode, Tim Bray)

39