Changed l'endianness de l'affichage d'od

Le
Rémi Moyen
Bonjour,

J'ai un fichier binaire où sont écrit des entiers (32 bits, non
signés) en format big-endian. Manque de pot, la machine sur laquelle
je travaille est little-endian. Du coup, si j'utilise od pour regarder
mon fichier, je me retrouve avec n'importe quoi (enfin, pas tout à
fait, mais pas ce que je veux).

Par exemple, si mon fichier (décodé) commence par "22 4 14", ça me
donne les octets (en décimal) "000 000 000 022 000 000 000 004 000 000
000 014". Lu par od sur ma machine, ça devient "369098752 67108864
234881024".

Je n'ai pas accès facilement à une machine big-endian sur laquelle od
se comporterait comme je veux, il faut donc que je trouve une solution
sur une machine little-endian.

Ma question est donc : comment je peux faire pour obtenir l'affichage
qui va bien ? Il me semble qu'il n'y a pas d'options pour forcer od à
considerer une endianness particulière (même si il a régulièrement =
des
discussions à ce sujet), ni de combinaisons d'options qui revienne au
même.

Quelqu'un connaît-il une (suite de) commande(s) qui permettrait de
retourner un (bout de) fichier binaire avant de le passer à od ? Ou un
autre outil similaire à od et qui permettrait de faire ça (j'ai
regardé rapidement hexdump, mais ça a l'air pareil) ? J'ai bien trouv=
é
des outils graphiques (khexedit, par exemple) qui font ça, mais
j'aimerais avoir quelque chose en ligne de commande et scriptable

Merci d'avance !
--
Rémi Moyen
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Cyrille Lefevre
Le #12866451
Rémi Moyen a écrit :
Bonjour,

J'ai un fichier binaire où sont écrit des entiers (32 bits, non
signés) en format big-endian. Manque de pot, la machine sur laquelle
je travaille est little-endian. Du coup, si j'utilise od pour regarder
mon fichier, je me retrouve avec n'importe quoi (enfin, pas tout à
fait, mais pas ce que je veux...).

Par exemple, si mon fichier (décodé) commence par "22 4 14", ça m e
donne les octets (en décimal) "000 000 000 022 000 000 000 004 000 00 0
000 014". Lu par od sur ma machine, ça devient "369098752 67108864
234881024".



la prochaine fois, précise quel commande tu utilises, les options qui
vont avec en l'occurrence...

dans le cas présent : od -i

un od -x et un od -c aurait été le bienvenue, ça m'aurait éviter de
chercher pourquoi tu avais 022 (-i) et moi 026 (-o)...

Je n'ai pas accès facilement à une machine big-endian sur laquelle od
se comporterait comme je veux, il faut donc que je trouve une solution
sur une machine little-endian.

Ma question est donc : comment je peux faire pour obtenir l'affichage
qui va bien ? Il me semble qu'il n'y a pas d'options pour forcer od à
considerer une endianness particulière (même si il a régulièrem ent des
discussions à ce sujet), ni de combinaisons d'options qui revienne au
même.

Quelqu'un connaît-il une (suite de) commande(s) qui permettrait de
retourner un (bout de) fichier binaire avant de le passer à od ? Ou u n
autre outil similaire à od et qui permettrait de faire ça (j'ai
regardé rapidement hexdump, mais ça a l'air pareil) ? J'ai bien tro uvé
des outils graphiques (khexedit, par exemple) qui font ça, mais
j'aimerais avoir quelque chose en ligne de commande et scriptable...



Bonjour,

suis sur que qq1 te fais ça en perl en une ligne... :)

$ cat c.pl
#!/usr/bin/perl

$usage = "Usage: '$0 <Source File> <Destination File>'";

$srcFile = shift @ARGV || die $usage;
$dstFile = shift @ARGV || die $usage;

open(SRCFILE, "$srcFile") || die "Unable to open file: $!n";
binmode SRCFILE;

open(DSTFILE, "> $dstFile") || die "Unable to open file: $!n";
binmode DSTFILE;

while (read(SRCFILE, $inWord, 4) == 4) {
$outWord = pack('V', unpack('N', $inWord));
print DSTFILE $outWord;
}

close(DSTFILE);
close(SRCFILE);

en attendant :

cat << 'EOF' > conv.c
#include
unsigned long
swap32 (unsigned long l) {
union {
unsigned long l;
struct {
unsigned char c1;
unsigned char c2;
unsigned char c3;
unsigned char c4;
} s;
} u;
unsigned char c;

u.l = l;

c = u.s.c1;
u.s.c1 = u.s.c4;
u.s.c4 = c;

c = u.s.c2;
u.s.c2 = u.s.c3;
u.s.c3 = c;

return u.l;
}
int
main () {
unsigned long l;
while (fread (&l, sizeof(l), 1, stdin) == 1) {
l = swap32 (l);
fwrite(&l, sizeof(l), 1, stdout);
}
return (0);
}
EOF

make conv

conv < input > output

Cordialement,

Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%
supprimer "%nospam% et ".invalid" pour me repondre.
Cyrille Lefevre
Le #12866441
Loic Tortay a écrit :
Le Tue, 8 Jul 2008 06:17:14 -0700 (PDT), Rémi Moyen a écrit :
[...]
Quelqu'un connaît-il une (suite de) commande(s) qui permettrait de
retourner un (bout de) fichier binaire avant de le passer à od ? Ou un
autre outil similaire à od et qui permettrait de faire ça (j'ai
regardé rapidement hexdump, mais ça a l'air pareil) ? J'ai bien tr ouvé
des outils graphiques (khexedit, par exemple) qui font ça, mais
j'aimerais avoir quelque chose en ligne de commande et scriptable...



Une solution pour changer « l'endianness » est d'utiliser "dd" :
dd conv=swab if=monfichier | od



Bonjour,

conv=swab travaille au niveau octet (8 bits), lui en entier (32 bits).

Cordialement,

Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%
supprimer "%nospam% et ".invalid" pour me repondre.
Stephane CHAZELAS
Le #12880911
2008-07-09, 01:56(+02), Cyrille Lefevre:
[...]
suis sur que qq1 te fais ça en perl en une ligne... :)


[...]

perl -pe 'BEGIN{$/=4} $_=pack V, unpack N'

--
Stéphane
Rémi Moyen
Le #14498951
On Jul 9, 12:56 am, Cyrille Lefevre <cyrille.lefevre-news
% wrote:

> Par exemple, si mon fichier (décodé) commence par "22 4 14", ça m e
> donne les octets (en décimal) "000 000 000 022 000 000 000 004 000 00 0
> 000 014". Lu par od sur ma machine, ça devient "369098752 67108864
> 234881024".

la prochaine fois, précise quel commande tu utilises, les options qui
vont avec en l'occurrence...



Hum, oui, j'y ai pas pensé, désolé. Je me suis dit que le problème
était suffisamment indépendant d'une commande en particulier, mais
c'est vrai que ça aurait été plus clair avec.

> Quelqu'un connaît-il une (suite de) commande(s) qui permettrait de
> retourner un (bout de) fichier binaire avant de le passer à od ? Ou u n
> autre outil similaire à od et qui permettrait de faire ça (j'ai
> regardé rapidement hexdump, mais ça a l'air pareil) ? J'ai bien tro uvé
> des outils graphiques (khexedit, par exemple) qui font ça, mais
> j'aimerais avoir quelque chose en ligne de commande et scriptable...



$usage = "Usage: '$0 <Source File> <Destination File>'";



Oui, mais non :-)

Le problème d'un truc comme ça (ou d'un programme en C, que j'ai déj à
plus ou moins en fait), c'est que ça convertit tout le fichier. Là, je
me bats avec des fichiers de 200 Go, je ne voudrais pas le dupliquer
uniquement pour ça, d'autant plus qu'en général je cherche juste à
décoder une poignée de valeurs au milieu du fichier pour débugger. En
fait, ce que je cherche idéalement, c'est une commande "blop" que je
pourrais utiliser par exemple comme ça :

$ dd if=bigfile skipB000 count@ | blop | od -tu4

(ou un truc que je pourrais combiner avec od -j, mais c'est sans doute
plus dur, là)

En fait, la même chose que ce que tu proposes, mais qui prenne son
entrée sur l'entrée standard et écrive sur la sortie standard, je
suppose. C'est peut-être trivial en perl, mais je ne connais pas assez
pour le faire... Je pourrais le faire en C (sauf que je connais rien
aux méchanismes pour lire en continu, pipe ou socket ou machin de ce
genre je suppose), mais en fait j'espérais qu'il y ait une solution
toute bête avec des commandes shell.

Mais merci quand même pour tes suggestions !
--
Rémi Moyen
Rémi Moyen
Le #14498941
On Jul 9, 12:56 am, Cyrille Lefevre <cyrille.lefevre-news
% wrote:
Loic Tortay a écrit :
> Une solution pour changer « l'endianness » est d'utiliser "dd" :
>    dd conv=swab if=monfichier | od

Bonjour,

conv=swab travaille au niveau octet (8 bits), lui en entier (32 bits).



Voui, hélas pour moi. Ça ne suffit donc pas à faire ce que je veux.
J'avoue que je ne connaissais pas dd -conv, j'aurais au moins
découvert une option de plus ! :-)

Merci quand même.
--
Rémi Moyen
Matthieu Moy
Le #14498931
Rémi Moyen
En fait, la même chose que ce que tu proposes, mais qui prenne son
entrée sur l'entrée standard et écrive sur la sortie standard, je
suppose. C'est peut-être trivial en perl, mais je ne connais pas assez
pour le faire... Je pourrais le faire en C (sauf que je connais rien
aux méchanismes pour lire en continu, pipe ou socket ou machin de ce
genre je suppose),



Si tu veux un truc qui s'insère dans

commande | ton-truc | autre-commande

il lit sur stdin et écrit sur stdout. getchar/putchar devraient suffire !

while (1) {
x1 = getchar();
x2 = getchar();
x3 = getchar();
x4 = getchar();
putchar(x4);
putchar(x3);
putchar(x2);
putchar(x1);
}

est pas loin de la solution (à la condition de terminaison près au moins).

--
Matthieu
Cyrille Lefevre
Le #14498921
Rémi Moyen a écrit :
Le problème d'un truc comme ça (ou d'un programme en C, que j'ai dé jà
plus ou moins en fait), c'est que ça convertit tout le fichier. Là, je
me bats avec des fichiers de 200 Go, je ne voudrais pas le dupliquer
uniquement pour ça, d'autant plus qu'en général je cherche juste à
décoder une poignée de valeurs au milieu du fichier pour débugger . En
fait, ce que je cherche idéalement, c'est une commande "blop" que je
pourrais utiliser par exemple comme ça :

$ dd if=bigfile skipB000 count@ | blop | od -tu4

(ou un truc que je pourrais combiner avec od -j, mais c'est sans doute
plus dur, là)

En fait, la même chose que ce que tu proposes, mais qui prenne son
entrée sur l'entrée standard et écrive sur la sortie standard, je
suppose. C'est peut-être trivial en perl, mais je ne connais pas asse z



ça tombe bien, c'est ce que fait le prog c posté...
sinon, le perl de Stéphane devrait suffire... grrr !

pour le faire... Je pourrais le faire en C (sauf que je connais rien
aux méchanismes pour lire en continu, pipe ou socket ou machin de ce
genre je suppose), mais en fait j'espérais qu'il y ait une solution
toute bête avec des commandes shell.



Cordialement,

Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%
supprimer "%nospam% et ".invalid" pour me repondre.
Rémi Moyen
Le #14498911
On Jul 9, 11:56 pm, Cyrille Lefevre <cyrille.lefevre-news
% wrote:

> $ dd if=bigfile skipB000 count@ | blop | od -tu4

> (ou un truc que je pourrais combiner avec od -j, mais c'est sans doute
> plus dur, là)

> En fait, la même chose que ce que tu proposes, mais qui prenne son
> entrée sur l'entrée standard et écrive sur la sortie standard, je
> suppose. C'est peut-être trivial en perl, mais je ne connais pas asse z

ça tombe bien, c'est ce que fait le prog c posté...



Ah oui, tiens, j'avais lu trop vite et pas vu qu'il utilisait stdin/
stdout et pas argv[1]/argv[2]. Bon, ben à défaut d'un truc en shell,
j'utiliserais ça ou une version perso avec quelques autres options qui
me servent souvent (mais j'aime moins avoir un truc compilé parce
qu'il faut que je garde le code source quelque part si je veux me
souvenir de comment ça marche -- ok, c'est pas sorcier, mais quand
même --, que ça ne marchera pas forcément sur toutes les machines,
etc.).

Merci.

sinon, le perl de Stéphane devrait suffire... grrr !



Chez moi, ça ne marche absolument pas (mais je connais rien en perl,
si ça se trouve c'est de ma faute) :

$ /bin/echo -n -e "26000000" | perl -pe 'BEGIN{$/=4} $_=pack
V, unpack N' | od -td1
Not enough arguments for unpack at -e line 1, at EOF
Execution of -e aborted due to compilation errors.
0000000

Comme j'ai pas la moindre idée de ce que fait le programme (je suis
capable de lire un programme pas trop compliqué, mais je ne connais
pas les particularités de perl. Du coup, BEGIN, /=, pack et unpack,
c'est de la magie noire, pour moi), je ne peux rien en faire :-(
--
Rémi Moyen
Nicolas George
Le #14498901
Rémi Moyen wrote in message
Not enough arguments for unpack at -e line 1, at EOF



Rajoute « , $_ » à la fin.
Stephane CHAZELAS
Le #14543021
2008-07-10, 09:34(+00), Nicolas George:
Rémi Moyen wrote in message
Not enough arguments for unpack at -e line 1, at EOF



Rajoute « , $_ » à la fin.



Le comportement a du changer dernierement, perldoc -f unpack me
dit:

unpack TEMPLATE,EXPR
unpack TEMPLATE
"unpack" does the reverse of "pack": it takes a
string and expands it out into a list of values.
(In scalar context, it returns merely the first
value produced.)

If EXPR is omitted, unpacks the $_ string.


(perl 5.10.0).

--
Stéphane
Publicité
Poster une réponse
Anonyme