Par défaut, votre appel à pack
est équivalent à ce qui suit :
struct.pack('@HcHH', port, flags, len(fragments), len(name))
Le résultat ressemble à ceci (imprimé avec '.'.join(f'{x:02X} for x in data')
):
33.05.40.00.04.00.0B.00
0 1 2 3 4 5 6 7
Le nombre 4 est codé dans les octets 4 et 5, en little endian, et 11 est codé dans les octets 6 et 7. L'octet 3 est un octet de remplissage, inséré par pack
pour aligner correctement les éléments suivants short
s sur une frontière paire.
Par le docs :
Note Par défaut, le résultat de l'empaquetage d'une structure C donnée inclut des octets de remplissage afin de maintenir un alignement correct pour les types C impliqués ; de même, l'alignement est pris en compte lors du dépaquetage. Ce comportement est choisi pour que les octets d'une structure empaquetée correspondent exactement à la disposition en mémoire de la structure C correspondante. Pour gérer les formats de données indépendants de la plate-forme ou omettre les octets de remplissage implicites, utilisez la commande standard
la taille et l'alignement au lieu de native
taille et alignement : voir Ordre, taille et alignement des octets pour les détails.
Pour supprimer l'octet d'alignement et justifier vos hypothèses sur la position des octets tout en conservant l'ordre natif des octets, utilisez
struct.pack('=HcHH', port, flags, len(fragments), len(name))
Vous pouvez également utiliser un ordre d'octet fixe en utilisant la commande <
o >
comme préfixe.
La solution "correcte" consiste à utiliser unpack
pour récupérer vos chiffres, de sorte que vous n'avez pas à vous soucier de l'endianness, du remplissage ou de quoi que ce soit d'autre, vraiment.