Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1751 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] conversion fichier binaire Big-Little Endian [RESOLU]

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] conversion fichier binaire Big-Little Endian [RESOLU]

n°1766778
Facewindu
Posté le 30-07-2008 à 15:56:50  profilanswer
 

Bonjour, je suis face à un petit problème.
 
J'ai un fichier binaire dont je change l'endianness octet par octet.
J'obtiens alors un deuxième fichier binaire.
En ouvrant ces deux fichiers avec un éditeur hexadécimal et en comparant quelques valeurs, j'ai vérifié que ma conversion était bonne.
Par exemple à l'adresse 0x000C426C du premier fichier, je trouve la valeur hexa 1C
à la même adresse dans l'autre fichier je trouve la valeur hexa 38.
1C(hexa)=00011100(binaire) et 38(hexa)=00111000(binaire)
donc la conversion est OK.
 
Ensuite j'utilise un autre prog (que je n'ai pas codé) qui me décode le fichier binaire en txt pour pouvoir le lire.
J'ai compilé cet outil de décodage sur PC et sur Station Sun.
Sur PC, pas de prob, tout s'affiche bien.
Par contre sur Sun, ça merde.
 
Pensez-vous que ça vient du truc de décodage, ou bien ma "preuve" convernant ma conversion sur les fichiers binaires ne suffit pas, et c'est dans mes binaires que ça merde ?
 
merci


Message édité par Facewindu le 06-08-2008 à 17:53:12
mood
Publicité
Posté le 30-07-2008 à 15:56:50  profilanswer
 

n°1766797
Un Program​meur
Posté le 30-07-2008 à 16:22:04  profilanswer
 

La boutitude ca concerne generalement(1) l'ordre des bytes dans des mots, pas l'ordre des bits dans des bytes.
 
(1) Du moins tel que vue par les programmeurs; si on fait des transmission bit par bit, il faut aussi s'occuper de l'ordre des bits dans les bytes; et rien ne garanti que ce sera le meme que l'ordre des bytes dans des mots.

n°1767246
Facewindu
Posté le 31-07-2008 à 12:57:48  profilanswer
 

Oui, tu as surement raison, faut que j'intervertisse mes Bytes et pas mes bits dans les Bytes.
Du coup ça me soulève un autre problème :
Les types de données stockées dans mon fichier binaire dépendent de plusieurs trucs, du coup ça me fait plein de cas à traiter.
Par exemple :
cas 1 : uint32, uint8, uint8
cas 2 : uint16, uint64, etc etc
(et j'ai pas mal de cas, genre une trentaine)
 
Comme ça là maintenant je vois qu'un seul moyen, c'est de faire un truc du genre :
dans le cas 1, tu prends les 4 premiers Bytes et tu les switches, puis le Byte suivant et tu le switches, etc etc
dans le cas 2, tu prends les 2 premiers, puis les 8 suivants, etc etc
 
Ca va être chiant de me taper tous les cas un par un.
Existe-til une méthode pour parcourir la mémoire Byte par Byte et savoir quand le Byte suivant appartient à une autre variable ?


Message édité par Facewindu le 31-07-2008 à 12:59:11
n°1767250
Joel F
Real men use unique_ptr
Posté le 31-07-2008 à 13:05:02  profilanswer
 

tu pourrais pas gruger et utiliser htons et ntohs à des fin détournés.
Sinon, t'as accés à la structure que tu lit/ecrit ? Si oui le mieux et de faire une fonction qui prend une instance de cette structure et le boutise avant de la sauver et vice et versa

n°1767263
Facewindu
Posté le 31-07-2008 à 13:36:44  profilanswer
 

oui j'ai accès à la structure (j'ai un pointeur sur le début de la structure et je connais normalement son type (un de mes cas) et son taille en Bytes.
Imaginons que je crée une fonction qui la prenne en instance, en quoi ça change par rapport à ce que j'ai expliqué avant ?
Comment je peux lui dire de boutiser chaque variable de la structure ?

n°1767274
Un Program​meur
Posté le 31-07-2008 à 13:48:46  profilanswer
 

D'apres ce que je comprends, la suggestion de Joel est ton traitement des cas.  Et je ne connais pas d'autres methodes.

n°1767278
Facewindu
Posté le 31-07-2008 à 14:01:35  profilanswer
 

ouais, bah je vais mettre les mains dans le camboui. Ca va être long et moche mais bon ...
J'avais aussi penser à faire une méthode très généraliste qui boutise une variable de n'importe quelle type, en mettant des void* et des typeof dedans, mais je me suis cassé les dents.

n°1767286
Joel F
Real men use unique_ptr
Posté le 31-07-2008 à 14:25:00  profilanswer
 

tu dois rester en C ? Car je me demande si dans boost::serialization t'as ça qui est tout géré de base

n°1767297
Facewindu
Posté le 31-07-2008 à 14:37:32  profilanswer
 

et oui, je dois rester en C :(
je vous tiens au courant (surement demain, voire lundi quand j'aurais fini) pour dire si ça marche.


Message édité par Facewindu le 31-07-2008 à 14:38:05
n°1767800
Facewindu
Posté le 01-08-2008 à 13:47:39  profilanswer
 

Du nouveau.
En fait, le mec qui a codé le premier fichier binaire a utilisé __atribute__((packed)) pour limiter la taille mémoire.
Du coup peut-être que vous pouvez m'indiquer si y a moyen de "unpacker" tout ça, histoire d'avoir mes variables qui sont pas à cheval sur des Bytes ?

mood
Publicité
Posté le 01-08-2008 à 13:47:39  profilanswer
 

n°1767811
Joel F
Real men use unique_ptr
Posté le 01-08-2008 à 13:57:23  profilanswer
 

si tu utilise aussi le même attribut pour tes structures ca devrait passer. Ensuite à toi de remettre tes données dans une structure non-packed

n°1767922
MagicBuzz
Posté le 01-08-2008 à 16:09:43  profilanswer
 

Juste pour ma culture (et désolé de pourrir le topic si c'est le cas) à quoi ça sert aujourd'hui d'utiliser encore le big endian ?
 
De mémoire de mes cours de système, le big endian a été inventé par intel je crois, afin d'optimiser le traîtement des grands nombres sur les processeurs 8 bits :
 
si on additionne deux entiers de 32 bits avec un processeur 8 bits, on est emmerdé car on doit commencer par le 4° byte, garder la retenue, passer au 3°, puis au 2° et enfin au 1°.
 
alors qu'en big endian, le byte "des unités" étant en premier, on fait le calcul dans l'odre des bytes en mémoire, ce qui est bien plus pratique.
 
mais maintenant que tous les processeurs sont 32 ou 64 bits, à quoi que sert d'avoir encore cette représentation puisque le processeur n'y gagne rien, au contraire, il doit remettre les bytes dans l'ordre avant de faire le calcul (enfin, du moins je suppose qu'il est câblé pour savoir faire le calcul directement en big endian en plus du sens normal du traîtement)... elle est encore beaucoup utilisée ?
 
et n'existe-t-il pas une variante pour les processeurs 32 bits qui manipulent des nombres de 64 ou 128 bits ? (c'est à dire non plus inverser les bytes, mais des paquets de 4 bytes)

Message cité 1 fois
Message édité par MagicBuzz le 01-08-2008 à 16:12:33
n°1767924
Joel F
Real men use unique_ptr
Posté le 01-08-2008 à 16:10:58  profilanswer
 

... c'est câblé point barre, jamais t'as besoin de te savoir ce qui se passe. Maintenant, ok, on arrête de faire du BE et du LE ...
Qui se tape tout les patchs pour un demi-milliard d'applications LE ou BE qui doivent lire des binaires natifs ?


Message édité par Joel F le 01-08-2008 à 16:11:32
n°1767930
MagicBuzz
Posté le 01-08-2008 à 16:15:02  profilanswer
 

nan mais je ne parle pas d'arrêter le support sur les processeurs :o (pourquoi tu veux systématiquement déformer mes propos pour me voler dans les plumes ?)
 
ma question est : aujourd'hui, à quoi ça sert, si à l'origine ça servait vraiment à ce que j'ai retenu de mes cours ?
 
et est-ce encore utilisé sur les compilateurs modernes (faits pour processeurs 32 ou 64 bits)
 
biensûr qu'il faut rester compatible, mais ma question n'a rien à voir avec la compatibilité, juste savoir s'il y a une utilité


Message édité par MagicBuzz le 01-08-2008 à 16:15:49
n°1767935
Joel F
Real men use unique_ptr
Posté le 01-08-2008 à 16:19:27  profilanswer
 

ça n'a rien avoir avec le compilateur :E c'est le processeur qui est comme ça c'est tout :E

 

Wiki a un bon exemple :

Citation :


Les nombres big-endian sont plus faciles à lire lorsqu'on débogue un programme car leur contenu est directement lisible sans avoir à changer l'ordre des octets constituant le nombre. Cela est dû au fait que l'ordre des chiffres est le même que celui de l'écriture normale.

 

Le mode little-endian présentait des avantages lorsque les processeurs utilisaient des tailles de registre variables, c’est-à-dire 8, 16 ou 32 bits. À partir d'une adresse mémoire donnée, on pouvait lire le même nombre en lisant 8, 16 ou 32 bits. Par exemple, le nombre 33 (0x21 en hexadécimal) s'écrit 21 00 00 00 en little endian en 32 bits, ce qui se lit toujours 21 quel que soit le nombre d'octets lus. Ceci est faux en big-endian car la première adresse change suivant le nombre d'octets à lire.

 

Y a pas d'avantage ou de désavantage inhérent, donc on fait ce qui nous arrange au moment de concevoir le proc et c'est tout.


Message édité par Joel F le 01-08-2008 à 16:21:15
n°1767944
MagicBuzz
Posté le 01-08-2008 à 16:27:46  profilanswer
 

ok.
donc j'avais mal compris mon cours. je croyais que c'était le programme qui gérait ça. mais non, c'est le processeur :jap: donc du coup, effectivement la question de l'utilité ne se pose même pas, au risque de se manger un cuisant échec commercial comme Intel et son I64 en voulant tout remettre à plat la structure de son proc


Message édité par MagicBuzz le 01-08-2008 à 16:28:42
n°1767965
xilebo
noone
Posté le 01-08-2008 à 16:59:05  profilanswer
 

MagicBuzz a écrit :

Juste pour ma culture (et désolé de pourrir le topic si c'est le cas) à quoi ça sert aujourd'hui d'utiliser encore le big endian ?
 
De mémoire de mes cours de système, le big endian a été inventé par intel je crois, afin d'optimiser le traîtement des grands nombres sur les processeurs 8 bits :
 
si on additionne deux entiers de 32 bits avec un processeur 8 bits, on est emmerdé car on doit commencer par le 4° byte, garder la retenue, passer au 3°, puis au 2° et enfin au 1°.
 
alors qu'en big endian, le byte "des unités" étant en premier, on fait le calcul dans l'odre des bytes en mémoire, ce qui est bien plus pratique.
 
mais maintenant que tous les processeurs sont 32 ou 64 bits, à quoi que sert d'avoir encore cette représentation puisque le processeur n'y gagne rien, au contraire, il doit remettre les bytes dans l'ordre avant de faire le calcul (enfin, du moins je suppose qu'il est câblé pour savoir faire le calcul directement en big endian en plus du sens normal du traîtement)... elle est encore beaucoup utilisée ?
 
et n'existe-t-il pas une variante pour les processeurs 32 bits qui manipulent des nombres de 64 ou 128 bits ? (c'est à dire non plus inverser les bytes, mais des paquets de 4 bytes)


Lors d'une formation sur l'écriture de modules linux, le formateur nous a expliqué que le choix du processeur (i.e. son endianess) est déterminant pour les performances selon l'utilisation que l'on va en faire.  
Par exemple, une application qui va faire du traitement réseau (un routeur, un firewall etc ...) sera toujours moins performant (selon ses dires) sur un processeur intel que sur un processeur basé sur du big endian car la pile TCP/IP a été développée sur une base big endian, et donc sur un processeur intel, on passe son temps à convertir (le fameux htons ). Inversement, le bus PCI (et plus récemment USB) a été créé en collaboration avec intel et fonctionne donc en little endian.
Ce qui signifie que dans certains cas, selon le processeur utiliser, on va passer beaucoup de temps ou non à convertir les données.
 
(Je me suis peut etre trompé sur certains points, n'étant pas un expert, mais l'idée est là).

n°1767966
Facewindu
Posté le 01-08-2008 à 17:01:21  profilanswer
 

Pour en revenir au sujet :

Joel F a écrit :

si tu utilise aussi le même attribut pour tes structures ca devrait passer. Ensuite à toi de remettre tes données dans une structure non-packed


Ok, on en revient alors au traitement au cas par cas que je devrais faire puisque ma structure varie grandement d'un cas à l'autre.

n°1767967
Joel F
Real men use unique_ptr
Posté le 01-08-2008 à 17:04:08  profilanswer
 

je ne vois pas comment tu peut t'en sortir autrement.
Pourrais tu filer un exemple minimaliste de ce que tu as comme structure

n°1767970
MagicBuzz
Posté le 01-08-2008 à 17:08:17  profilanswer
 

merci pour ces informations :jap:

n°1767971
Facewindu
Posté le 01-08-2008 à 17:08:36  profilanswer
 

ouais
alors de tête(je l'ai pas sous les yeux)
struct __attribute__ ((__packed__)) {
int blabla;
int truc:6;
machinchose ma_struct;
}header 1 ;
 
struct __attribute__ ((__packed__)){
char monChar:1;
int monInt:7;
} machinchose;
 
avec bcp plus de variables, et bcp plus de structures imbriquées.
Et par exemple, si blabla=12, la structure imbriquée sera totalement différente que dans le cas blabla=13 ....


Message édité par Facewindu le 03-08-2008 à 18:47:23
n°1768437
Gf4x3443
Killing perfection
Posté le 03-08-2008 à 12:32:55  profilanswer
 

xilebo a écrit :


Lors d'une formation sur l'écriture de modules linux, le formateur nous a expliqué que le choix du processeur (i.e. son endianess) est déterminant pour les performances selon l'utilisation que l'on va en faire.
Par exemple, une application qui va faire du traitement réseau (un routeur, un firewall etc ...) sera toujours moins performant (selon ses dires) sur un processeur intel que sur un processeur basé sur du big endian car la pile TCP/IP a été développée sur une base big endian, et donc sur un processeur intel, on passe son temps à convertir (le fameux htons ).

 

Rien à voir avec l'archi initiale de dev de la pile DARPA. Cela vient du fait que le netwok byte order est BE alors que x86 est LE.

 

Maintenant, rien ne t'empeches de faire du code sale et de ne pas utiliser les htons et compagnie, du moment que les systèmes utiliseront la même convention aux deux bouts.

 

Il faut savoir que c'est une problèmatique qui ne s'applique qu'aux types binaires. Si la communication ne se fait qu'en chaine de caractères, on se fiche du BE/LE. D'ailleurs, les primitives htons/ntohs n'encapsulent pas toutes les conventions, si tu communiques des double, à toi de te faire ta moulinette, ou d'utiliser des usines à gaz comme XDR.

 

MagicBuzz> aujourd'hui, la mode n'est pas à l'économie de BP mais à la simplification du code, donc à s'astreint généralement la problèmatique BE/LE en évitant les types binaires, et en encapsulant les données sous forme de chaines de caractères (qui n'ont pas ce problème), quitte à utiliser des dialectes plus haut niveau comme XML, pour le typage.


Message édité par Gf4x3443 le 03-08-2008 à 12:33:49

---------------
Petit guide Kerberos pour l'administrateur pressé
n°1768649
el muchach​o
Comfortably Numb
Posté le 03-08-2008 à 21:14:12  profilanswer
 

Rassure-moi, on ne fait pas du XML pour du bas niveau, tout de même ?


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
n°1768653
Gf4x3443
Killing perfection
Posté le 03-08-2008 à 21:23:11  profilanswer
 

el muchacho a écrit :

Rassure-moi, on ne fait pas du XML pour du bas niveau, tout de même ?

 

Ca dépend, t'entends quoi par "bas niveau"?

 

Pour mon cas (netbsd), on s'en sert de plus en plus dans le noyau, avec un parser simplifié fait pour avoir le moins d'overhead possible (la proplib: http://www.daemon-systems.org/man/proplib.3.html ).

 

Apple fait la même chose, c'est plus clean pour passer des syscall/ioctl sans avoir à se préoccuper de types complexes ou abscons, ou faire des couches de compatibilités sans se péter les couilles (surtout que linux les fait à sa sauce, très particulière).

 

Niveau perf, aucune différence.

 

Sur réseau en revanche, j'ai jamais vu (à part pour les XML RPC, genre fermes de virtualisation - c'est à la mode, avec XMPP, ca permet de faire des trucs très sympa). XDR reste quand même la référence.


Message édité par Gf4x3443 le 03-08-2008 à 21:23:57

---------------
Petit guide Kerberos pour l'administrateur pressé
n°1768694
bjone
Insert booze to continue
Posté le 03-08-2008 à 23:47:59  profilanswer
 

xilebo a écrit :


Lors d'une formation sur l'écriture de modules linux, le formateur nous a expliqué que le choix du processeur (i.e. son endianess) est déterminant pour les performances selon l'utilisation que l'on va en faire.  
Par exemple, une application qui va faire du traitement réseau (un routeur, un firewall etc ...) sera toujours moins performant (selon ses dires) sur un processeur intel que sur un processeur basé sur du big endian car la pile TCP/IP a été développée sur une base big endian, et donc sur un processeur intel, on passe son temps à convertir (le fameux htons ). Inversement, le bus PCI (et plus récemment USB) a été créé en collaboration avec intel et fonctionne donc en little endian.
Ce qui signifie que dans certains cas, selon le processeur utiliser, on va passer beaucoup de temps ou non à convertir les données.
 
(Je me suis peut etre trompé sur certains points, n'étant pas un expert, mais l'idée est là).


 
bof.
le coût de transformation est plustôt ridicule devant le reste des traitements internes à la pile.

n°1770323
Facewindu
Posté le 06-08-2008 à 17:52:59  profilanswer
 

Pour en revenir au sujet, je me fais des tableaux de char, contenant des 0 ou des 1. Ca me fait une sorte de tableau de bits, et après je me démerde avec au cas par cas.
donc y a plus de prob.
merci !

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] conversion fichier binaire Big-Little Endian [RESOLU]

 

Sujets relatifs
[RESOLU]Installation extension GD[resolu] List et explosion de la conso mémoire
[Résolu]Probleme Surlignement ligne avec JavascriptConvertir 1 colonne d'un fichier txt avec une fonction (ktime)
[Delphi] Conversion de types (single et string)[Résolu] problème background-repeat
mysqldump via PHP -> fichier vide ![résolu] waitFor() qui reste bloqué...
Modification de données dans un fichierInterprétation de variable dans un fichier
Plus de sujets relatifs à : [C] conversion fichier binaire Big-Little Endian [RESOLU]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR