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

Changed l'endianness de l'affichage d'od

13 réponses
Avatar
Rémi Moyen
Bonjour,

J'ai un fichier binaire o=F9 sont =E9crit des entiers (32 bits, non
sign=E9s) 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 =E0
fait, mais pas ce que je veux...).

Par exemple, si mon fichier (d=E9cod=E9) commence par "22 4 14", =E7a me
donne les octets (en d=E9cimal) "000 000 000 022 000 000 000 004 000 000
000 014". Lu par od sur ma machine, =E7a devient "369098752 67108864
234881024".

Je n'ai pas acc=E8s facilement =E0 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 =E0
considerer une endianness particuli=E8re (m=EAme si il a r=E9guli=E8rement =
des
discussions =E0 ce sujet), ni de combinaisons d'options qui revienne au
m=EAme.

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

Merci d'avance !
--
R=E9mi Moyen

10 réponses

1 2
Avatar
Cyrille Lefevre
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 <stdio.h>

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.
Avatar
Cyrille Lefevre
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.
Avatar
Stephane CHAZELAS
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
Avatar
Rémi Moyen
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
Avatar
Rémi Moyen
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
Avatar
Matthieu Moy
Rémi Moyen writes:

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
Avatar
Cyrille Lefevre
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.
Avatar
Rémi Moyen
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 "
Avatar
Nicolas George
Rémi Moyen wrote in message
:
Not enough arguments for unpack at -e line 1, at EOF



Rajoute « , $_ » à la fin.
Avatar
Stephane CHAZELAS
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
1 2