Vous êtes ici : Accueil Tutoriels Conversions

Conversions

Les liens entre chaînes de caractères, octets, octal et nombres et hexadécimaux peuvent parfois être obscurs. A travers un mini-exemple et à l'aide de quelques explications, ce mini-tutoriel vous permet de vous y retrouver.

Types de données

Nombres

Lorsque l'on pense nombre, on pense souvent Entier, ce qui est le cas dans ce tutoriel. Un nombre entier est un objet représenté par la classe int et qui peut aller de 0 à l'infini et peut être positif ou négatif.

L'utilisation seule de digits représente un nombre entier.

En Python 3, il n'y a pas de limites à la représentation (sur laquelle il n'est pas nécessaire de s'étendre outre mesure) et donc pas de notion plus complexe que l'utilisation de la classe int. Cette classe contient l'ensemble des méthodes liées aux opérateurs qui permettent de faire les opérations mathématiques classiques.

>>> 2**10000
19950631168807583848837421626835850838234968318861924548520089498529438830221946631919961684036194597899331129423209124271556491349413781117593785932096323957855730046793794526765246551266059895520550086918193311542508608460618104685509074866089624888090489894838009253941633257850621568309473902556912388065225096643874441046759871626985453222868538161694315775629640762836880760732228535091641476183956381458969463899410840960536267821064621427333394036525565649530603142680234969400335934316651459297773279665775606172582031407994198179607378245683762280037302885487251900834464581454650557929601414833921615734588139257095379769119277800826957735674444123062018757836325502728323789270710373802866393031428133241401624195671690574061419654342324638801248856147305207431992259611796250130992860241708340807605932320161268492288496255841312844061536738951487114256315111089745514203313820202931640957596464756010405845841566072044962867016515061920631004186422275908670900574606417856951911456055068251250406007519842261898059237118054444788072906395242548339221982707404473162376760846613033778706039803413197133493654622700563169937455508241780972810983291314403571877524768509857276937926433221599399876886660808368837838027643282775172273657572744784112294389733810861607423253291974813120197604178281965697475898164531258434135959862784130128185406283476649088690521047580882615823961985770122407044330583075869039319604603404973156583208672105913300903752823415539745394397715257455290510212310947321610753474825740775273986348298498340756937955646638621874569499279016572103701364433135817214311791398222983845847334440270964182851005072927748364550578634501100852987812389473928699540834346158807043959118985815145779177143619698728131459483783202081474982171858011389071228250905826817436220577475921417653715687725614904582904992461028630081535583308130101987675856234343538955409175623400844887526162643568648833519463720377293240094456246923254350400678027273837755376406726898636241037491410966718557050759098100246789880178271925953381282421954028302759408448955014676668389697996886241636313376393903373455801407636741877711055384225739499110186468219696581651485130494222369947714763069155468217682876200362777257723781365331611196811280792669481887201298643660768551639860534602297871557517947385246369446923087894265948217008051120322365496288169035739121368338393591756418733850510970271613915439590991598154654417336311656936031122249937969999226781732358023111862644575299135758175008199839236284615249881088960232244362173771618086357015468484058622329792853875623486556440536962622018963571028812361567512543338303270029097668650568557157505516727518899194129711337690149916181315171544007728650573189557450920330185304847113818315407324053319038462084036421763703911550639789000742853672196280903477974533320468368795868580237952218629120080742819551317948157624448298518461509704888027274721574688131594750409732115080498190455803416826949787141316063210686391511681774304792596709376
>>> (1234567890*32**2*12+17)**42
39979702123775380360693046008682672199204987925033078872446534014823412643608430419952893995779297766609788531748545212347864235475710025075969340533435224715263474932891009497271620045369033976053884811590559287802730743575440922948015817296038998632967648635862151739592780450618438038037034245304192989273903864242739870861017742615681227294580789839535148325641279969129396539421561218122765627803410182358099280708905493741895825272663361179945492930541558670978947408061868215920931638863299549245525538197234228368805121056705367800453090401623969

Les octets

Les octets sont des nombres, écrits sous une représentation binaire de 8 digits, c'est à dire un nombre qui peut être écrit avec 8 chiffres maximum, en base 2. Les chiffres de base 2 sont 0 et 1, ce qui autorise 2**8, soit 256 possibilités

Un octet peut donc représenter un nombre compris entre 0 et 255 (il est dit non signé) ou alors un nombre entre -128 et 127 (il est dit signé).

Pour construire des nombres plus grands, il faut alors utiliser plusieurs octets. Ainsi, pour des entiers non signés, voici les limites pour une représentation sur 1, 2, 2 (calculé autrement), 4, 8 et 16 octets&nbs);:

>>> 2**8
256
>>> (2**8)**2
65536
>>> 2**(8*2)
65536
>>> 2**(8*4)
4294967296
>>> 2**(8*8)
18446744073709551616
>>> 2**(8*16)
340282366920938463463374607431768211456

L'octet est la base de l'informatique, puisque c'est sous cette forme que tout est représenté, stocké.

Les chaînes de caractères

Les chaînes de caractères sont délimitées de part et d'autres par l'utilisation des quotes ou doubles-quotes. En Python, il n'y a aucune différence entre ces deux symboles. Les composantes des chaînes de caractères sont les caractères qui peuvent être constitués de tout ce que l'on peut imaginer (et qui se trouve sur un clavier ou peut être séquencé à partir d'un clavier, pour ls caractères chinois par exemple) : Numérique, alphabétique (à partir de tous les alphabets latins ou autres), ponctuation, symboles (y compris monétaires).

En Python 3, ces caractères sont représentés en utilisant la table Unicode qui permet de décrire chaque caractère comme une séquence de 1, 2, 3 ou 4 octets, ce qui laisse entrevoir 4294967296 possibilités (bien moins sont utilisées).

Le lien entre l'octet et la chaîne de caractère est donc là : de la même manière que l'on peut représenter un nombre sous forme d'octet (en sachant s'il est signé ou non), on peut représenter un caractère sous forme d'un à quatre octets.

Or le fait de se baser sur l'Unicode est une pratique récente (mais qui se généralise). Auparavant, la représentation devait se faire sur un seul octet. Il fallait donc choisir 256 caractères et lier chacun à une représentation particulière.

Pour la plupart des alphabets, en particulier les latins, cela ne pose pas vraiment de problèmes. Il a été créé des tables de caractères composées de 128 caractères communs (c'est à dire partagés par chaque table) et de 128 autres variables. Ainsi, chaque langue pouvait positionner ses caractères particuliers. Pour comprendre une chaîne de caractère, il fallait avoir la bonne table, c'est à dire connaître le caractère rattaché à chaque représentation sous forme d'octet. Ce pont est réalisé par les fonctions ordinal (ord) et la réciproque (str).

Ce qu'il convient de retenir est qu'en Python 3, les notions ont été clarifiées puisqu'une chaîne de caractère est systématiquement en Unicode et que sa traduction au regard d'une des tables de caractère locale est clairement nommée octets, puisque c'est la classe bytes qui gère cette donnée.

Octal et hexadécimal

De la même manière que l'on peut représenter un nombre en base 10, 60 (pour les égyptiens) ou 2, on peut le représenter en base 8 ou 16.

L'octal est la représentation en base 8 d'un nombre. Un octet est la représentation en base 2 et avec 8 chiffres

La conversion entre représentation octale ou hexadécimale et décimale se fait ainsi :

>>> int('256', 8)
174
>>> '%o' % 174
'256'
>>> '%x' % 174
'ae'
>>> int('ae', 16)
174
>>> '%o' % int('ff', 16)
'377'
>>> '%x' % int('1000', 8)
'200'

Quelque soit la manière dont on les représente, il ne s'agit ici de rien d'autre que des nombres.

Exemple

Conversion entre une chaîne de caractère et un octet

En Python 3, le concept est simple. La chaîne de caractère est un objet de type str et il permet de passer à une séquence d'octets en précisant la table de caractère à utiliser (ou locale). Ceci se fait à l'aide de la méthode encode.

>>> "J'ai gagné 10€".encode('iso-8859-15')
b"J'ai gagn\xe9 10\xa4"

On obtient bien une séquence d'octets, la représentation de ce dernier commençant par le préfixe b devant les quotes ou doubles-quotes. Cette séquence d'octets peut être interprétée comme une suite de nombre. D'ailleurs, on peut faire le test suivant:

>>> "J'ai gagné 10€".encode('iso-8859-15')[0]
74"

Il faut noter que si l'on tente d'utiliser une table de caractère qui ne contient pas tous les caractères utilisés dans la chaîne, on obtient une erreur :

>>> "J'ai gagné 10€".encode('iso-8859-1')
Traceback (most recent call last):
  File "", line 1, in
UnicodeEncodeError: 'latin-1' codec can't encode character '\u20ac' in position 13: ordinal not in range(256)

Ainsi, il faut retenir que pour passer d'une chaîne de caractère représentée à l'aide d'une première table de caractère à la même chaîne représentée à l'aide d'une seconde table, il faudra passer par la case Unicode en décodant la première chaîne pour la réencoder par la suite. Python 3 apporte une clarification en ce sens que la classe str ne contient que la méthode encode alors que la classe bytes ne contient que la méthode decode.

Conversion un nombre et un hexadécimal

L'exemple typique de cette conversion est utilisée lorsque l'on transforme la représentation web standard d'une couleur en un 3-uplet de couleurs (Rouge, Vert, Bleu) 

def color_web2rvb(web):
    rvb = int(web[1:], 16)
    return int(rvb//256**2), int(rvb%256**2/256), rvb%256

Le parti a été pris ici d'utiliser les fonctions mathématiques pour bien montrer qu'il s'agit de nombres, mais il existe une autre voie qui aurait consisté à diviser la variable web en trois parties de deux caractères et à traiter chacun séparément.

Voici la fonction réciproque :

@rvb_comprehension
def color_rvb2web(r, v, b):
    return '#%02x%02x%02x' % (r, v, b)

Le formatage est ici utilisé afin d'afficher des hexadécimaux et de s'assurer que chaque chiffre soit représenté sur deux caractères en remplissant à gauche par des 0.

Enfin, le bonus du tutoriel est un petit décorateur qui permet de faire en sorte d'appeler la fonction color_rvb2web en y passant les trois paramètres ou en y passant un 3-uplet.

def rvb_comprehension(func):
    def wrapped(*args):
        if len(args) == 1 and type(args[0]) == tuple:
            return func(*args[0])
        return func(*args)
    return wrapped
Mots-clés associés : , , , , ,
Spinner