You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

python-14.md 4.4 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. % Programmation avec Python (chapitre 14)
  2. % Dimitri Merejkowsky
  3. \center \huge Parlons de binaire
  4. # Bits et octets
  5. * Un bit (*bit* en anglais) c'est la valeur 1 ou 0
  6. * Un octet (*byte* en anglais) c'est une suite de 8 bits
  7. # À retenir
  8. **Ces paquets de 8 ne veulent rien dire en eux-mêmes**.
  9. Ils n'ont de sens que dans le cadre d'une *convention*.
  10. Détaillons.
  11. # Bases
  12. On peut *interpréter* bits et octets comme des nombres
  13. ```
  14. 10: 0..9 305 305 3*100 + 0*10 + 5*1
  15. 2: 01 5 101 1*4 + 0*2 + 1*1
  16. 16: 0..9..F 3490 DA2 (d=13)*256 + (a=10)*16 + 2*1
  17. ```
  18. # Valeurs possibles
  19. Le nombre de valeurs possible augmente *très* rapidement avec le nombre d'octets:
  20. * 1 octet: $2^8$: 255
  21. * 2 octets: $2^{16}$: 65.536
  22. * 4 octets: $2^{32}$: 4.294.967.296
  23. # Bases en Python
  24. ```python
  25. >>> 5
  26. 5
  27. >>> 0b101
  28. 5
  29. >>> 0xda2
  30. 3490
  31. ```
  32. ```python
  33. >>> bin(5)
  34. "0b101"
  35. >>> hex(3490)
  36. "0xda2"
  37. ```
  38. # Poids des bits
  39. ```python
  40. 0b0010010 # 18
  41. 0b0010011 # 19
  42. 0b1010010 # 82
  43. ```
  44. Le premier bit est plus "fort" que le dernier - little endian
  45. # Manipuler des octets en Python
  46. Avec `bytearray` par exemple:
  47. ```python
  48. data = bytearray(
  49. [0b1100001,
  50. 0b1100010,
  51. 0b1100011
  52. ]
  53. )
  54. # equivalent:
  55. data = bytearray([97,98,99])
  56. # equivalent aussi:
  57. data = bytearray([0x61, 0x62, 0x63]
  58. ```
  59. # Texte
  60. On peut interpréter des octets comme du texte - c'est la table ASCII
  61. ![ascii table](img/ascii-table.png)
  62. # ASCII - remarques
  63. * C'est *vieux* - 1960
  64. * Le A est pour American
  65. * Ça sert à *envoyer* du texte sur des terminaux d'où les "caractères" non-imprimables dans la liste
  66. * Mais c'est une convention *très* utilisée
  67. * Techniquement, on n'a besoin que de 7 bits, mais on préfère envoyer des octets
  68. # Utiliser ASCII en Python
  69. Avec `chr` et `ord`
  70. ```python
  71. >>> chr(98)
  72. 'b'
  73. >>> ord('a')
  74. 97
  75. ```
  76. # Affichage des bytearrays en Python
  77. Python utilise ASCII pour afficher les bytearrays si les caractères sont "imprimables"
  78. ```python
  79. >>> data = bytearray([97,98,99])
  80. >>> data
  81. bytearray(b"abc")
  82. ```
  83. Et `\x` et le code hexa sinon:
  84. ```python
  85. >>> data = bytearray([7, 69, 76, 70])
  86. >>> data
  87. bytearray(b"\x07ELF")
  88. ```
  89. # Types
  90. La variable `b"abc"` est une "chaîne d'octets", de même que `"abc"` est une "chaîne de caractères".
  91. Python apelle ces types `bytes` et `str`:
  92. ```python
  93. >>> type("abc")
  94. str
  95. >>> type(b"abc")
  96. bytes
  97. ```
  98. Notez bien que ce qu'affiche Python n'est qu'une *interpétation* d'une séquence d'octets.
  99. # bits versus bytearray
  100. De la même manière qu'on ne peut pas un caractère dans une string, on ne peut
  101. pas modifier un bit - ou un octet dans un `bytes`.
  102. ```python
  103. >>> a = "foo"
  104. >>> a[0] = "f"
  105. TypeError: 'str' object does not support item assignment
  106. >>> b = b"foo"
  107. >>> b[0] = 1
  108. TypeError: 'bytes' object does not support item assignment
  109. ```
  110. # bits versus bytearray (2)
  111. Par contre on peut modifier un bytearray
  112. ```python
  113. >>> b = bytearray(b"foo")
  114. >>> b[0] = 103
  115. >>> b
  116. bytearray("goo")
  117. ```
  118. # Conversion octets - texte
  119. Avec `encode()` et `decode()`:
  120. ```python
  121. >>> text = "hello"
  122. >>> text.encode("ascii")
  123. b"hello"
  124. >>> octets = b"goodbye"
  125. >>> text = octets.decode("ascii")
  126. "goodbye"
  127. ```
  128. # Plus loin que l'ASCII
  129. Pas de caractères accentués dans ASCII. Du coup, on a d'autres *conventions* qu'on appelle "encodage".
  130. ```python
  131. # latin-1: utilisé sur certains vieux sites
  132. # souvent européens
  133. >>> bytearray([233]).decode('latin-1')
  134. 'é'
  135. ```
  136. ```python
  137. # cp850: dans l'invite de commande Windows
  138. >>> bytearray([233]).decode('cp850')
  139. 'Ú'
  140. ```
  141. Mais ça, c'était avant.
  142. # UTF-8
  143. * La table unicode - caractère -> codepoint
  144. * Un encodage qui a mis tout le monde d'accord
  145. * Compatible avec ASCII
  146. # UTF-8 en pratique
  147. * Certains caractères sont représentés par 2 octets ou plus:
  148. ![utf8 exemple](img/utf8.png)
  149. *note: toutes les séquences d'octets ne sont pas forcément valides*
  150. # Conséquences
  151. * Peut représenter *tout* type de texte (latin, chinois, coréen, langues disparues, ....)
  152. * On ne peut pas accéder à la n-ème lettre directement dans une chaîne unicode, il faut parcourir lettre par lettre
  153. # Fichiers
  154. ```python
  155. with open("fichier.txt", "r") as f:
  156. contents = f.read() # type: str
  157. ```
  158. \vfill
  159. ```python
  160. with open("fichier.txt", "rb") as f:
  161. contents = f.read() # type: bytes
  162. ```
  163. # Conclusions
  164. * On utilise souvent le binaire pour échanger entre Python et le monde extérieur
  165. * Le 'plain text' n'existe pas: tout texte a un *encodage*, et il vous faut connaître cet encodage
  166. * Si vous avez le choix, utilisez UTF-8