J'ai ABC123EFFF.
Je veux avoir 001010101111000001001000111110111111111111 (c'est-à-dire une reproduction binaire avec, par exemple, 42 chiffres et des zéros au début).
Comment?
Pour résoudre le problème zéro arrière gauche:
my_hexdata = "1a"
scale = 16 ## equals to hexadecimal
num_of_bits = 8
bin(int(my_hexdata, scale))[2:].zfill(num_of_bits)
Il donnera 00011010 au lieu de la version réduite.
import binascii
binary_string = binascii.unhexlify(hex_string)
Lis
Renvoie les données binaires représentées par la chaîne hexadécimale spécifiée en tant que paramètre.
bin(int("abc123efff", 16))[2:]
>>> bin( 0xABC123EFFF )
'0b1010101111000001001000111111111111111111'
Convertir l'hex en binaire
J'ai ABC123EFFF.
Je veux avoir 001010101111000001001000111110111111111111 (c'est-à-dire binaire Repr. Avec, disons, 42 chiffres et des zéros non significatifs).
Les nouvelles chaînes de caractères f dans Python 3.6 vous permettent de le faire en utilisant une syntaxe très concise:
>>> f'{0xABC123EFFF:0>42b}'
'001010101111000001001000111110111111111111'
ou pour rompre avec la sémantique:
>>> number, pad, rjust, size, kind = 0xABC123EFFF, '0', '>', 42, 'b'
>>> f'{number:{pad}{rjust}{size}{kind}}'
'001010101111000001001000111110111111111111'
Ce que vous dites réellement, c'est que vous avez une valeur dans une représentation hexadécimale et que vous souhaitez représenter une valeur équivalente en binaire.
La valeur de l'équivalence est un entier. Mais vous pouvez commencer par une chaîne, et pour visualiser en binaire, vous devez terminer par une chaîne.
Nous avons plusieurs moyens directs d’atteindre cet objectif, sans recourir à des tranches.
Tout d’abord, avant de pouvoir effectuer une quelconque manipulation binaire, convertissez-le en int (je suppose que cela se présente sous la forme d’une chaîne, et non sous forme littérale):
>>> integer = int('ABC123EFFF', 16)
>>> integer
737679765503
alternativement, nous pourrions utiliser un littéral entier exprimé en hexadécimal:
>>> integer = 0xABC123EFFF
>>> integer
737679765503
Nous devons maintenant exprimer notre entier sous forme de représentation binaire.
format
Puis passez à format
:
>>> format(integer, '0>42b')
'001010101111000001001000111110111111111111'
Ceci utilise le mini-langage de la spécification de formatage.
Pour décomposer cela, voici la forme grammaticale:
[[fill]align][sign][#][0][width][,][.precision][type]
Pour en faire une spécification de nos besoins, nous excluons simplement les choses dont nous n'avons pas besoin:
>>> spec = '{fill}{align}{width}{type}'.format(fill='0', align='>', width=42, type='b')
>>> spec
'0>42b'
et juste passer que pour formater
>>> bin_representation = format(integer, spec)
>>> bin_representation
'001010101111000001001000111110111111111111'
>>> print(bin_representation)
001010101111000001001000111110111111111111
str.format
Nous pouvons utiliser cela dans une chaîne en utilisant la méthode str.format
:
>>> 'here is the binary form: {0:{spec}}'.format(integer, spec=spec)
'here is the binary form: 001010101111000001001000111110111111111111'
Ou tout simplement mettre la spécification directement dans la chaîne d'origine:
>>> 'here is the binary form: {0:0>42b}'.format(integer)
'here is the binary form: 001010101111000001001000111110111111111111'
Montrons les nouvelles f-strings. Ils utilisent les mêmes règles de formatage mini-langage:
>>> integer = 0xABC123EFFF
>>> length = 42
>>> f'{integer:0>{length}b}'
'001010101111000001001000111110111111111111'
Mettons maintenant cette fonctionnalité dans une fonction pour encourager la réutilisabilité:
def bin_format(integer, length):
return f'{integer:0>{length}b}'
Et maintenant:
>>> bin_format(0xABC123EFFF, 42)
'001010101111000001001000111110111111111111'
Si vous voulez simplement encoder les données sous forme de chaîne d'octets en mémoire ou sur disque, vous pouvez utiliser la méthode int.to_bytes
, qui n'est disponible que dans Python 3:
>>> help(int.to_bytes)
to_bytes(...)
int.to_bytes(length, byteorder, *, signed=False) -> bytes
...
Et puisque 42 bits divisés par 8 bits par octet sont égaux à 6 octets:
>>> integer.to_bytes(6, 'big')
b'\x00\xab\xc1#\xef\xff'
"{0:020b}".format(int('ABC123EFFF', 16))
Voici une façon assez crue de le faire en utilisant des manipulations de bits pour générer les chaînes binaires.
Le bit clé à comprendre est:
(n & (1 << i)) and 1
Ce qui générera un 0 ou un 1 si le ième bit de n est activé.
import binascii
def byte_to_binary(n):
return ''.join(str((n & (1 << i)) and 1) for i in reversed(range(8)))
def hex_to_binary(h):
return ''.join(byte_to_binary(ord(b)) for b in binascii.unhexlify(h))
print hex_to_binary('abc123efff')
>>> 1010101111000001001000111110111111111111
Edit: en utilisant le "nouvel" opérateur ternaire ceci:
(n & (1 << i)) and 1
Deviendrait:
1 if n & (1 << i) or 0
(Quel TBH je ne suis pas sûr que ce soit lisible)
C'est une légère retouche de la solution de Glen Maynard, qui, selon moi, est la bonne façon de le faire. Il ajoute simplement l'élément de remplissage.
def hextobin(self, hexval):
'''
Takes a string representation of hex data with
arbitrary length and converts to string representation
of binary. Includes padding 0s
'''
thelen = len(hexval)*4
binval = bin(int(hexval, 16))[2:]
while ((len(binval)) < thelen):
binval = '0' + binval
return binval
Je l'ai sorti d'une classe. Supprimez simplement self,
si vous travaillez dans un script autonome.
bin(int("abc123efff", 16))[2:]
'1010101111000001001000111110111111111111'
`bin(int("abc123efff", 16))[2:].zfill(50)`
'00000000001010101111000001001000111110111111111111'
(Le nombre 50
indiquera à zfill
que vous souhaitez compléter la chaîne avec des zéros jusqu'à ce que la longueur de la chaîne soit égale à 50
.)
hex -> décimal puis décimal -> binaire
#decimal to binary
def d2b(n):
bStr = ''
if n < 0: raise ValueError, "must be a positive integer"
if n == 0: return '0'
while n > 0:
bStr = str(n % 2) + bStr
n = n >> 1
return bStr
#hex to binary
def h2b(hex):
return d2b(int(hex,16))
Remplacez chaque chiffre hexadécimal par les 4 chiffres binaires correspondants:
1 - 0001
2 - 0010
...
a - 1010
b - 1011
...
f - 1111
Autrement:
import math
def hextobinary(hex_string):
s = int(hex_string, 16)
num_digits = int(math.ceil(math.log(s) / math.log(2)))
digit_lst = ['0'] * num_digits
idx = num_digits
while s > 0:
idx -= 1
if s % 2 == 1: digit_lst[idx] = '1'
s = s / 2
return ''.join(digit_lst)
print hextobinary('abc123efff')
def conversion():
e=raw_input("enter hexadecimal no.:")
e1=("a","b","c","d","e","f")
e2=(10,11,12,13,14,15)
e3=1
e4=len(e)
e5=()
while e3<=e4:
e5=e5+(e[e3-1],)
e3=e3+1
print e5
e6=1
e8=()
while e6<=e4:
e7=e5[e6-1]
if e7=="A":
e7=10
if e7=="B":
e7=11
if e7=="C":
e7=12
if e7=="D":
e7=13
if e7=="E":
e7=14
if e7=="F":
e7=15
else:
e7=int(e7)
e8=e8+(e7,)
e6=e6+1
print e8
e9=1
e10=len(e8)
e11=()
while e9<=e10:
e12=e8[e9-1]
a1=e12
a2=()
a3=1
while a3<=1:
a4=a1%2
a2=a2+(a4,)
a1=a1/2
if a1<2:
if a1==1:
a2=a2+(1,)
if a1==0:
a2=a2+(0,)
a3=a3+1
a5=len(a2)
a6=1
a7=""
a56=a5
while a6<=a5:
a7=a7+str(a2[a56-1])
a6=a6+1
a56=a56-1
if a5<=3:
if a5==1:
a8="000"
a7=a8+a7
if a5==2:
a8="00"
a7=a8+a7
if a5==3:
a8="0"
a7=a8+a7
else:
a7=a7
print a7,
e9=e9+1
J'ai ajouté le calcul du nombre de bits à remplir à la solution d'Onedinkenedi. Voici la fonction résultante:
def hextobin(h):
return bin(int(h, 16))[2:].zfill(len(h) * 4)
Où 16 correspond à la base à partir de laquelle vous effectuez la conversion (hexadécimale) et 4 correspond au nombre de bits dont vous avez besoin pour représenter chaque chiffre, ou enregistrez la base 2 de l'échelle.
j'ai un petit espoir coupé qui aide :-)
input = 'ABC123EFFF'
for index, value in enumerate(input):
print(value)
print(bin(int(value,16)+16)[3:])
string = ''.join([bin(int(x,16)+16)[3:] for y,x in enumerate(input)])
print(string)
d'abord, j'utilise votre entrée et l'énumère pour obtenir chaque symbole. puis je le convertis en binaire et trim de la 3ème position à la fin. L'astuce pour obtenir le 0 est d'ajouter la valeur maximale de l'entrée -> dans ce cas toujours 16 :-)
la forme courte est la méthode de jointure. Prendre plaisir.