1.2 Encodings UTF-8 has several convenient properties: UTF-8 is one of the most commonly used encodings, and Python often defaults to using it. UTF stands for “Unicode Transformation Format”, and the ‘8’ means that 8-bit values are used in the encoding. (There are also UTF-16 and UTF-32 encodings, but they are less frequently used than UTF-8.) UTF-8 uses the following rules: Therefore this encoding isn’t used very much, and people instead choose other encodings that are more efficient and convenient, such as UTF-8. This representation is straightforward but using it presents a number of problems. To summarize the previous section: a Unicode string is a sequence of code points, which are numbers from 0 through $_{0x10FFFF}$(1,114,111 decimal). This sequence of code points needs to be represented in memory as a set of code units , and code units are then mapped to 8-bit bytes. The rules for translating a Unicode string into a sequence of bytes are called a character encoding , or just an encoding . The first encoding you might think of is using 32-bit integers as the code unit, and then using the CPU’s representation of 32-bit integers. In this representation, the string “Python” might look like this: P y t h o n 0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 3 6. UTF-8 is a byte oriented encoding. The encoding specifies that each character is represented by a specific sequence of one or more bytes. This avoids the byte-ordering issues that can occur with integer and word oriented encodings, like UTF-16 and UTF-32, where the sequence of bytes varies depending on the hardware on which the string was encoded. 5. If bytes are corrupted or lost, it’s possible to determine the start of the next UTF-8-encoded code point and resynchronize. It’s also unlikely that random 8-bit data will look like valid UTF-8. 4. UTF-8 is fairly compact; the majority of commonly used characters can be represented with one or two bytes. 3. A string of ASCII text is also valid UTF-8 text. 2. A Unicode string is turned into a sequence of bytes that contains embedded zero bytes only where they rep- resent the null character (U+0000). This means that UTF-8 strings can be processed by C functions such as$_{strcpy()}$ and sent through protocols that can’t handle zero bytes for anything other than end-of-string markers. 1. It can handle any Unicode code point. 2. If the code point is >= 128, it’s turned into a sequence of two, three, or four bytes, where each byte of the sequence is between 128 and 255. 1. If the code point is < 128, it’s represented by the corresponding byte value. 2. It’s very wasteful of space. In most texts, the majority of the code points are less than 127, or less than 255, so a lot of space is occupied by$_{0x00}$ bytes. The above string takes 24 bytes compared to the 6 bytes needed for an ASCII representation. Increased RAM usage doesn’t matter too much (desktop computers have gigabytes of RAM, and strings aren’t usually that large), but expanding our usage of disk and network bandwidth by a factor of 4 is intolerable. 3. It’s not compatible with existing C functions such as$_{strlen()}$ , so a new family of wide string functions would need to be used. 1. It’s not portable; different processors order the bytes differently.