Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

ASCII

ord() and chr()

is actually encoded in memory according to ASCII:
https://www.man7.org/linux/man-pages/man7/ascii.7.html

a -> 97
b -> 98
c -> 99
d -> 100

 -> 10
e -> 101
f -> 102
g -> 103
h -> 104

 -> 10
'a'

write into a text file

inspect that file with a hex editor - e.g. you can use vs-code and install the HEX Editor extension

you will see that, with ASCII-only characters, your file has exactly one byte per character

non-ASCII & UTF-8

let us now consider a text with French accents and cedilla - any non-ASCII character would do

inspection

a -> 97
b -> 98
ç -> 231
d -> 100

 -> 10
é -> 233
f -> 102
g -> 103
h -> 104

 -> 10
('0xe7', '0xe9')
('0b11100111', '0b11101001')

again, note that chr() and ord() are the inverse of one another

('ç', 231)

write into a text file

read back

and as we read bytes here, and we have more bytes than the initial text had characters

(12, 10)

it adds up, since the each of the 2 alien characters will need 2 bytes each to be encoded
(European characters usually take 2 bytes; some more exoctic chars can take 3 or 4 bytes)

UTF-8 logic

this table describes how the UTF8 encoding works:

a visual example

on a sample 4-characters string: été\n

let’s check that

on our own data

b'ab\xc3\xa7d\n\xc3\xa9fgh\n'

let us number the contents of raw

012   3   45 6   7   89
ab\xc3\xa7d\n\xc3\xa9fgh\n
byte 195 0xc3 0b11000011
byte 167 0xa7 0b10100111
byte 195 0xc3 0b11000011
byte 169 0xa9 0b10101001

sounds good

decode manually (gory details)

this is totally optional of course, but if we wanted to do the decoding ourselves...
(you may skip to the next section)

'0b11100000'
('é', 'ç')

exercise

use this table to write a complete UTF-8 decoder

UTF-32

let us now take a quick look at the UTF-32 encoding
this is a fixed size encoding, meaning each character will use 4 bytes
this is convenient e.g. when you need to do direct access to the n−thn-th character in a file

write with UTF-32

let’s write our text with 2 alien characters in a second file

size and BOM

however the total file size is not exactly 4∗n4*n, and this is due to something called the BOM (Byte Order Mark)

file has 44 bytes
10

44 is because

b'\xff\xfe\x00\x00'

which indeed matches the UTF-32 little-endian (LE) BOM as shown on Byte order mark

decoding is way easier

with that in mind, it is easier to

for example: decode the ç in our initial string

'ç'

so this means it gets encoded in the file on 4 bytes starting at offset
4 + 4 * index

b'\xe7\x00\x00\x00'

because it is little endian - see Endianness - it means we have to mirror the data bytes to get the actual value

231
'ç'