Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Simplhex

7 réponses
Avatar
Méta-MCI \(MVP\)
Bonjour !

Après avoir perdu je ne sais combien de secondes avec des listes en
intention, pour décoder une chaîne en hexadécimal, je me suis aperçu,
puis rappelé, que ça existait en standard :

print '507974686f6e'.decode('hex')

Maintenant, qu'est-ce que je fais de mes essais de code foireux ? Hop!
Poubelle.

@-salutations
--
Michel Claveau

7 réponses

Avatar
Pierre Maurette
Bonjour !

Après avoir perdu je ne sais combien de secondes avec des listes en
intention, pour décoder une chaîne en hexadécimal,


Comme ça ?:

hh = {
'0':0
,'1':1
,'2':2
,'3':3
,'4':4
,'5':5
,'6':6
,'7':7
,'8':8
,'9':9
,'a':10
,'b':11
,'c':12
,'d':13
,'e':14
,'f':15
}
s = '507974686f6e'
print ''.join([chr(16 * hh[s[x]] + hh[s[x + 1]]) for x in range(0,
len(s), 2)])

je me suis aperçu, puis
rappelé, que ça existait en standard :

print '507974686f6e'.decode('hex')


Et dans l'autre sens:

print 'Python'.encode('hex')

Maintenant, qu'est-ce que je fais de mes essais de code foireux ? Hop!
Poubelle.


Comme celui-ci:

print ''.join([hex(ord(x))[2:] for x in 'Python'])

--
Pierre Maurette

Avatar
Méta-MCI \(MVP\)
Salut !

Il y en a qui ont l'air d'avoir beaucoup de temps libre...
;-)

Bonne journée.

Michel Claveau
Avatar
Cémoi
Dans le même ordre d'idée: convertir une chaine de caractères
représentant un nombre hexadécimal en décimal, e.g. 'ac78' => 44152,
sans utiliser ni dictionnaires, ni listes en intention ni module dédié:

print int('ac78', 16)

A noter que int('0xac78', 16) fonctionne également.

Parfois j'aurai tendance à penser qu'un module standard ( 'num', 'base',
'convert', ...) qui centraliserait toutes les fonctions de conversion
depuis/vers le binaire, octal, hexa, chaine de caractères, ... ne serait
pas complètement idiot.
Mais bon, je ne suis qu'un modeste amateur qui essaie déjà d'utiliser
proprement ce qui existe (rien que ça! ;).

@+

Laurent

Bonjour !

Après avoir perdu je ne sais combien de secondes avec des listes en
intention, pour décoder une chaîne en hexadécimal, je me suis aperçu,
puis rappelé, que ça existait en standard :

print '507974686f6e'.decode('hex')

Maintenant, qu'est-ce que je fais de mes essais de code foireux ? Hop!
Poubelle.

@-salutations


Avatar
Cémoi
Sans vouloir mépriser votre intelligence, on peut aussi jouer avec des
chaines représentant du binaire:

print int('010001110001', 2)




1137

Les zéros de début de chaine ne posent pas de problème particulier.
Comme dirait Yves Calvi: "voilà quoi ...!"

@+

Laurent

P.S.: en temps d'exécution, c'est rapide puisqu'une chaine de 320
millions de bits se convertit en entier long en moins de 2 secondes sur
mon PC x86.

Dans le même ordre d'idée: convertir une chaine de caractères
représentant un nombre hexadécimal en décimal, e.g. 'ac78' => 44152,
sans utiliser ni dictionnaires, ni listes en intention ni module dédié:

print int('ac78', 16)

A noter que int('0xac78', 16) fonctionne également.

Parfois j'aurai tendance à penser qu'un module standard ( 'num', 'base',
'convert', ...) qui centraliserait toutes les fonctions de conversion
depuis/vers le binaire, octal, hexa, chaine de caractères, ... ne serait
pas complètement idiot.
Mais bon, je ne suis qu'un modeste amateur qui essaie déjà d'utiliser
proprement ce qui existe (rien que ça! ;).

@+

Laurent




Avatar
Pierre Maurette
Dans le même ordre d'idée: convertir une chaine de caractères représentant un
nombre hexadécimal en décimal, e.g. 'ac78' => 44152, sans utiliser ni
dictionnaires, ni listes en intention ni module dédié:

print int('ac78', 16)

A noter que int('0xac78', 16) fonctionne également.

Parfois j'aurai tendance à penser qu'un module standard ( 'num', 'base',
'convert', ...) qui centraliserait toutes les fonctions de conversion
depuis/vers le binaire, octal, hexa, chaine de caractères, ... ne serait pas
complètement idiot.


Il me semble - mais sans doute des trucs m'ont échappé - que dans le
sens valeur -> chaine dans une base, il n'y a que hex().
Et hex() est assez caca. Le 0x... serait un faux problème, hex(val)[2:]
devant le faire. Il ne gère pas le complément à 2, ce qui est assez
embêtant. hex(-10) donne -0xa. Donc pour enlever le 0x, il faut faire
hex(val).split('x')[-1]. Et il ne sort même pas un nombre pair de
digits derrière le 0x.
Résultat je me suis fait un machin pour afficher àpeu près proprement,
et faciliter le boulot par exemple sur les formats de couleur (HTML /
CSS):

#! /usr/bin/env python
# -*- coding: utf-8 -*-

__all__ = ['val2binc2', 'val2hexc2', 'completeAndAddSeparators',
'completeAndAddSeparators', 'leftComplete', 'computeNumBits']

import sys


################################################################################
def computeNumBits(value, signedúlse):
"""Calcule le nombre de bits dans la série 8, 16, 32, 64, 128, 256,
etc.
nécessaires pour contenir value.
La représentation envisagée est du binaire naturel ou en
complément à 2.

arguments:
- value, un entier
- signed, booléen, à True si on souhaite une représentation
signée.
Si value est négatif, signed est "forcé" à True.

retourne:
- Le nombre de bits.

"""
n, max, neg = 8, 256, (value < 0)
if signed or neg:
value *= (1, -1)[neg]
value <<= 1
value -= neg
while max <= value:
n *= 2
max *= max
return n


################################################################################
def leftComplete(chaine, pacs, remplissage='0'):
"""Complète la chaîne pour une longueur multiple de Pi[pacs].

arguments:
- chaine: la chaine à traiter
- pacs: liste des nombres d'éléments. Voir putseparators()
- remplissage: le caractère de remplissage. Si vaut 'bin' (ou
'hex'), le caractère
de remplissage sera '0' ou '1' (ou '0' ou 'F') pour propager le
bit de signe


retourne:
- La chaine, modifiée si possible.

"""

if remplissage == 'bin':
remplissage = chaine[0]
elif remplissage == 'hex':
remplissage = ('F', '0')[chaine[0] < '8']
L = len(chaine)
P = reduce(lambda x,y: x * y, pacs)
return (P - (L % P)) * remplissage + chaine


################################################################################
def __addSeparators(chaine, seps, pacs):
"""Insère des séparateurs dans une chaine.

arguments:
- chaine: la chaine à traiter
- seps, pacs: les listes des séparateurs et de nombre d'éléments.
Dans ces listes, les éléments sont dans l'ordre du plus bas niveau
vers le plus général.
Les nombres d'éléments par blocs (dans pacs) sont exprimés en
blocs du niveau précédent. pacs[0]
est en caractères, pacs[1] en blocs de pacs[0] caractères +
séparateurs de niveau 0, etc.


retourne:
- La chaine, modifiée si possible.

"""

n = len(seps)
if n == len(pacs) and n > 0:
seps.append('') #seps[-1] sera '', pour la première itération de la
boucle
for i in range(n):
chaine = [seps[i-1].join(chaine[x:x + pacs[i]]) for x in range(0,
len(chaine), pacs[i])]
chaine = seps[n-1].join(chaine)
return chaine


################################################################################
def addSeparators(chaine, seps, pacs):
"""Insère des séparateurs dans une chaine. Place les groupes
incomplets en début de chaine.

arguments:
- chaine: la chaine à traiter
- seps, pacs: les listes des séparateurs et de nombre d'éléments.
Dans ces listes, les éléments sont dans l'ordre du plus bas niveau
vers le plus général.
Les nombres d'éléments par blocs (dans pacs) sont exprimés en
blocs du niveau précédent. pacs[0]
est en caractères, pacs[1] en blocs de pacs[0] caractères +
séparateurs de niveau 0, etc.


retourne:
- La chaine, modifiée si possible.

"""

return __addSeparators(chaine[::-1], seps, pacs)[::-1]


################################################################################
def completeAndAddSeparators(chaine, seps, pacs, remplissage):
"""Insère des séparateurs dans une chaine. Complete d'abord la chaine
à gauche pour éviter
les groupes incomplets.

arguments:
- chaine: la chaine à traiter
- seps, pacs: les listes des séparateurs et de nombre d'éléments.
Dans ces listes, les éléments sont dans l'ordre du plus bas niveau
vers le plus général.
Les nombres d'éléments par blocs (dans pacs) sont exprimés en
blocs du niveau précédent. pacs[0]
est en caractères, pacs[1] en blocs de pacs[0] caractères +
séparateurs de niveau 0, etc.


retourne:
- La chaine, modifiée si possible.

"""

return __addSeparators(leftComplete(chaine, pacs, remplissage), seps,
pacs)


################################################################################
def val2hexc2(value, hexdigits=0, signedúlse):
"""Fabrique la chaîne de l'expression hexadécimale de value.
Formatée sur hexdigits chiffres, ou plus si nécessaire.

arguments:
- value, un entier
- hexdigits, nombre de chiffres souhaités.
- signed, booléen, à True si on souhaite une représentation
signée.
Si value est négatif, signed est "forcé" à True.

retourne:
- La chaîne de l'expression hexadécimale.

"""
bits = max(hexdigits * 4, computeNumBits(value, signed))
abovevalue = 1 << bits
firststring = hex((abovevalue + value) %
abovevalue).upper().split('X')[-1].rstrip('L').lstrip('0')
return '0' * ((bits / 4) - len(firststring)) + firststring


################################################################################
def val2binc2(value, bits, signedúlse):
"""Fabrique la chaîne de l'expression binaire de value.
Formattée sur bits chiffres (bits), ou plus si nécessaire.

arguments:
- value, un entier
- bits, nombre de bits souhaités.
- signed, booléen, à True si on souhaite une représentation
signée.
Si value est négatif, signed est "forcé" à True.

retourne:
- La chaîne de l'expression binaire.

"""
return ''.join({
'0':'0000'
,'1':'0001'
,'2':'0010'
,'3':'0011'
,'4':'0100'
,'5':'0101'
,'6':'0110'
,'7':'0111'
,'8':'1000'
,'9':'1001'
,'A':'1010'
,'B':'1011'
,'C':'1100'
,'D':'1101'
,'E':'1110'
,'F':'1111'
}[c.upper()] for c in val2hexc2(value, bits/4, signed))


################################################################################

################################################################################
def __tests():
for x in (1, -1, 5, 65536):
print x, 't', addSeparators(val2binc2(x, 64, True), ['.', ' ', '
', ' '], [2, 3, 2, 2])
print x, 't', completeAndAddSeparators(val2binc2(x, 64, True),
['.', ' ', ' ', ' '], [2, 3, 2, 2], 'bin')
print hex(-1), 't', val2hexc2(-1)
for x in range(65530, 65540):
print x, 't', addSeparators(val2hexc2(x, 16, True), [' ', ' '],
[2, 4])
print x, 't', addSeparators(val2hexc2(x, 4, True), [' ', ' '],
[2, 4])
print hex(-10), 't', val2hexc2(-10), 't', hex(-10)[2:],
hex(-10).split('x')[-1]
print hex(300), 't', val2hexc2(300), 't', hex(300)[2:],
hex(300).split('x')[-1]
print val2hexc2(255)
print val2hexc2(256 * 256 * 256 * 256 - 1)
ColorVector = (100, 95, 230)
print '#' + val2hexc2(ColorVector[0]) + val2hexc2(ColorVector[1]) +
val2hexc2(ColorVector[2])
print addSeparators('123456', [' '], [4])
print addSeparators(leftComplete('123456', [4], '0'), [' '], [4])
print completeAndAddSeparators('123456', [' '], [4], '_')
print addSeparators('12345678123456781234567812345678', ['.', ' '],
[2, 4])
print __addSeparators('123456781234567812345678123456', ['.', ' '],
[2, 4])
print addSeparators('123456781234567812345678123456', ['.', ' '],
[2, 4])
print completeAndAddSeparators('123456781234567812345678123456',
['.', ' '], [2, 4], '0')
print leftComplete('4FFFFF', [4], 'hex')
sys.exit(0)

if __name__ == '__main__':
__tests()



--
Pierre Maurette

Avatar
Cémoi
Dans le même ordre d'idée: convertir une chaine de caractères
représentant un nombre hexadécimal en décimal, e.g. 'ac78' =>
44152, sans utiliser ni dictionnaires, ni listes en intention ni
module dédié:

print int('ac78', 16)

A noter que int('0xac78', 16) fonctionne également.

Parfois j'aurai tendance à penser qu'un module standard ( 'num',
'base', 'convert', ...) qui centraliserait toutes les fonctions de
conversion depuis/vers le binaire, octal, hexa, chaine de
caractères, ... ne serait pas complètement idiot.


Il me semble - mais sans doute des trucs m'ont échappé - que dans le
sens valeur -> chaine dans une base, il n'y a que hex().


Tu as aussi '%x' % nombre_entier, ou '%X' % nombre_entier si tu veux des
majuscules.
Il n'y a pas d'effet de bord avec '0x' en début de chaine retournée.
Si tu veux un nombre figé de digits tu peux utiliser par exemple '%04x'
% nombre_entier pour récupérer 4 digits en minuscules.
Si tu as besoin que la chaine retournée commence par '0x' ou '0X' il
faut utiliser '%#x' % nombre_entier ou '%#X' % nombre_entier respectivement.
On peut l'utiliser de manière concurrente à la spécification du nombre
de digits.
Le format de conversion '%o' % nombre_entier permet d'appréhender la
conversion en octal.


Je constate que je ne suis pas le seul à rencontrer des petits soucis de
manipulation de formats, d'autant plus qu'on a passé sous silence le
format binaire.
AMHA '%caractères_magiques' appartient à l'histoire ancienne héritée du
C et n'est pas ce qui se fait de plus pythonique.
Quel serait votre avis sur une PEP visant à centralisant les fonctions de
conversion des nombres (entiers au minimum) ?

En espérant que cela aide,

Laurent


Avatar
nntpman68
Aussie bien a savoir:


int('13',0) # conversion de decimal a decimal
int('013',0) # conversion de octal a decimal
int('0x13',0) # conversion de hex a decimal

je utilese ca pour le parametres donner dans la ligne de command


int(argv[0],0) # comme ca l'utilisateur put choisir (selon le prefix)
si il veut entrer en decimal, hex ou octal

Malheureusement (et contrairement a perl) le prefix '0b' n'est pas
traiter comme prefix pour les chiffres binair.


bye


N


Cémoi wrote:
Dans le même ordre d'idée: convertir une chaine de caractères
représentant un nombre hexadécimal en décimal, e.g. 'ac78' => 44152,
sans utiliser ni dictionnaires, ni listes en intention ni module dédié:

print int('ac78', 16)

A noter que int('0xac78', 16) fonctionne également.

Parfois j'aurai tendance à penser qu'un module standard ( 'num', 'base',
'convert', ...) qui centraliserait toutes les fonctions de conversion
depuis/vers le binaire, octal, hexa, chaine de caractères, ... ne serait
pas complètement idiot.
Mais bon, je ne suis qu'un modeste amateur qui essaie déjà d'utiliser
proprement ce qui existe (rien que ça! ;).

@+

Laurent

Méta-MCI (MVP) a écrit :
Bonjour !

Après avoir perdu je ne sais combien de secondes avec des listes en
intention, pour décoder une chaîne en hexadécimal, je me suis aperçu,
puis rappelé, que ça existait en standard :

print '507974686f6e'.decode('hex')

Maintenant, qu'est-ce que je fais de mes essais de code foireux ?
Hop! Poubelle.

@-salutations