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 3.6 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. 2: 01 5 101 1*4 + 0*2 + 1*1
  15. 10: 0..9 305 305 3*10 + 0*10 + 5*1
  16. 16: 0..9..F 3490 DA2 (d=13)*256 + (a=10)*16 + 2*1
  17. ```
  18. # Bases en Python
  19. ```python
  20. >>> 0b101
  21. 5
  22. >>> 0xda2
  23. 3490
  24. ```
  25. ```python
  26. >>> bin(5)
  27. "0b101"
  28. >>> hex(3490)
  29. "0xda2"
  30. ```
  31. # Manipuler des octets en Python
  32. Avec `bytearray` par exemple:
  33. ```python
  34. data = bytearray(
  35. [0b1100001,
  36. 0b1100010,
  37. 0b1100011,
  38. 0b1100100]
  39. )
  40. # equivalent:
  41. data = bytearray([97,98,99])
  42. # equivalent aussi:
  43. data = bytearray([0x61, 0x62, 0x63]
  44. ```
  45. # Texte
  46. On peut interpréter des octets comme du texte - c'est la table ASCII
  47. ![ascii table](img/ascii-table.png)
  48. # ASCII - remarques
  49. * C'est *vieux* - 1960
  50. * Le A est pour American
  51. * Ça sert à *envoyer* du texte sur des terminaux d'où les "caractères" non-imprimables dans la liste
  52. * Mais c'est une convention *très* utilisée
  53. # Utiliser ASCII en Python
  54. Avec `ord` et `chr`
  55. ```python
  56. >>> ord('a')
  57. 97
  58. >>> chr(98)
  59. 'b'
  60. ```
  61. # Affichage des bytearrays en Python
  62. Python utilise ASCII pour afficher les bytearrays si les caractères sont "imprimables"
  63. ```python
  64. >>> data = bytearray([97,98,99])
  65. >>> data
  66. bytearray(b"abc")
  67. ```
  68. Et `\x` et le code hexa sinon:
  69. ```python
  70. >>> data = bytearray([7, 69, 76, 70])
  71. >>> data
  72. bytearray(b'\x07ELF')
  73. ```
  74. # Types
  75. La variable `b"abc"` est une "chaîne de bits", de même que `"abc"` est une "chaîne de caractères".
  76. Python apelle ces types `bytes` et `str`:
  77. ```python
  78. >>> type("abc")
  79. str
  80. >>> type(b"abc")
  81. bytes
  82. ```
  83. Notez bien que ce qu'affiche Python n'est qu'une *interpétation* du tableau de bits.
  84. # bits versus bytearray
  85. De la même manière qu'on ne peut pas un caractère dans une string, on ne peut
  86. pas modifier un bit - ou un octet dans un `bytes`.
  87. ```python
  88. >>> a = "foo"
  89. >>> a[0] = "f"
  90. TypeError: 'str' object does not support item assignment
  91. >>> b = b"foo"
  92. >>> b[0] = 1
  93. TypeError: 'bytes' object does not support item assignment
  94. ```
  95. # bits versus bytearray (2)
  96. Par contre on peut modifier un bytearray
  97. ```python
  98. >>> b = bytearray(b"foo")
  99. >>> b[0] = 95
  100. >>> b
  101. bytearray("_oo")
  102. ```
  103. # Plus loin que l'ASCII
  104. Pas de caractères accentuès dans ASCII. Du coup, on a d'autres *conventions* qu'on appelle "encodage".
  105. ```python
  106. # latin-1: utilisé sur certains vieux sites
  107. # - souvent européens
  108. >>> bytearray([0b11101001]).decode('latin-1')
  109. 'é'
  110. ```
  111. ```python
  112. # cp850: dans l'invite de commande Windows
  113. >>> bytearray([0b11101001]).decode('cp850')
  114. 'Ú'
  115. ```
  116. Mais ça, c'était avant. Avant UTF-8, un encodage qui a mis tout le monde d'accord.
  117. # UTF-8 en pratique
  118. * Compatible avec ASCII
  119. * Mais certains caractères sont représentés par 2 octets ou plus:
  120. ![utf8 exemple](img/utf8.png)
  121. # Conséquences
  122. * Peut représenter *tout* type de texte (latin, chinois, coréen, langues disparues, ....)
  123. * On ne peut pas accéder à la n-ème lettre directement dans une chaîne unicode, il faut parcourir lettre par lettre
  124. * Et toutes les séquences de bits ne sont pas forcément valides
  125. # Conclusions
  126. * On utilise souvent le binaire pour échanger entre Python et le monde extérieur
  127. * Python vous cache un peu ça en utilisant UTF-8 par défaut donc ça marche souvent
  128. * Le 'plain text' n'existe pas: tout texte a un *encodage*, et il vous faut connaître cet encodage
  129. * Si vous avez le choix, utilisez UTF-8