選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
このリポジトリはアーカイブされています。 ファイルの閲覧とクローンは可能ですが、プッシュや、課題・プルリクエストのオープンはできません。

python-14.md 4.4 KiB

5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
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