concernant uniquement le message 88
si j'ai 010011 ca me fera 2^^0+2^1+2^4
et pas de sépration par 4 cette fois ci
concernant uniquement le message 88
si j'ai 010011 ca me fera 2^^0+2^1+2^4
et pas de sépration par 4 cette fois ci
Ah... j'avais pas non plus intégré le non groupage ...
Mais je répète ma question : ceci concerne les 3 colonnes de la ligne 88 ?
il y a pas de souci, j'ai vu ca en lisant le programme.
oui pour les trois colonnes de la ligne 88
Je n'ai pas pu tester correctement, car les exemples de résultat que tu as donnés dernièrement ne correspondent pas au fichier d'entrée que tu avais fournis précédemment.
Voici une nouvelle version du script:
J'ai quand même un doute ... il peut y avoir des erreurs. Soit précis dans tes exemples, et donne toutes les colonnes attendues pour chaque entrée (ainsi que le fichier d'entrée correspondant).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map glob($_), grep /[\*\?]/, @in; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier backup (l'ancien fichier d'entrée) en lecture # et le fichier de sortie en écriture (le nouveau fichier d'entrée) open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?,).*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say "$timestamp$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp$code"; } } } } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186 if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201 if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210 if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225 if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 74-51), undef, 0); # Decoder les bits 108 à 122 push @decoded, bin2hex(substr($bitcode, 107, 122-108), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 122 : 146, $bit82 eq "0" ? 138-123 : 162-147), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }
j'ai modifié des bits mais ca c'est mon erreurnouveau fichier, la ligne 15h52,24 donne 2162685 en temps normal et ici la moitié à un bit près, la deuxieme colonne c'est ok et l'autre 1036
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map glob($_), grep /[\*\?]/, @in; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier backup (l'ancien fichier d'entrée) en lecture # et le fichier de sortie en écriture (le nouveau fichier d'entrée) open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?,).*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say "$timestamp$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp$code"; } } } } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186 if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201 if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210 if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225 if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 74-51), undef, 0); # Decoder les bits 108 à 121 push @decoded, bin2hex(substr($bitcode, 107, 121-108), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 121 : 145, $bit82 eq "0" ? 136-122 : 160-146), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }
5_2162685_2_sam - Copie.txt5_2162685_2_sam - Copie.txt
mais je vérifie quelque chose , car c'est une hsitoire d'un bit
au niveau des bits 51 à 74, j'ai refait à la main et les bits font bien 2162685
et le rpgramme lui le trouve comme s'il prennait les bits 51 à 73
j'ai mis ca et ca fonctionne
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 75-51), undef, 0);
le 74 était il inclus?
apreil pour les derniers bits.
je trouve bien mes résultats.
Je fais un fichier plus complet et je regarde tout ca demain.
mais à priori tout fonctionne
MERCI INFINIEMENT!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Il faut corriger la ligne 12
et mettre ça à la place :
Code : Sélectionner tout - Visualiser dans une fenêtre à part @in = map glob($_), grep /[\*\?]/, @in;
Mais ça n'a rien à voir avec l'erreur. Pour le reste, tu as raison, j'ai fait une erreur dans le calcul de la longueur des entiers en nombre de bits.
Code : Sélectionner tout - Visualiser dans une fenêtre à part @in = map /[\*\?]/ ? glob($_) : $_, @in;
Voici le script corrigé :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map /[\*\?]/ ? glob($_) : $_, @in; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier backup (l'ancien fichier d'entrée) en lecture # et le fichier de sortie en écriture (le nouveau fichier d'entrée) open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?,).*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say "$timestamp$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp$code"; } } } } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186 if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201 if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210 if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225 if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 74-50), undef, 0); # Decoder les bits 108 à 122 push @decoded, bin2hex(substr($bitcode, 107, 122-107), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 122 : 146, $bit82 eq "0" ? 138-122 : 162-146), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }
avec ce script ca me donne pas les deux dernieres colonnes de bonne.
je trouve 30 et 4145 au lieu de 15 et 1036
moi j'ai mis (j'avais mal écris également les bits que je voulais )
et ca fonctionne comme ca.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 75-51), undef, 0); # Decoder les bits 108 à 122 push @decoded, bin2hex(substr($bitcode, 107, 122-108), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 121 : 145, $bit82 eq "0" ? 137-122 : 161-146), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }
si je garde" mon " script je dois changer la ligne 12 seulement c'est bien ca?
dernière remarquer le m s'affiche pas? et il y a pas le cas "cm" pour 00 non ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map /[\*\?]/ ? glob($_) : $_, @in; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier backup (l'ancien fichier d'entrée) en lecture # et le fichier de sortie en écriture (le nouveau fichier d'entrée) open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?,).*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say "$timestamp$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp$code"; } } } } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186 if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201 if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210 if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225 if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 75-51), undef, 0); # Decoder les bits 108 à 122 push @decoded, bin2hex(substr($bitcode, 107, 122-108), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 121 : 145, $bit82 eq "0" ? 137-122 : 161-146), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }
enfin normalement tout devrait etre en metre, mais bon c'est une possibilité
On est bien d'accord que la 2e colonne (bits 108 à 122) contient 15 bits et que la 3e colonne (bits 123 à 138 ou 147 à 162) contient 16 bits ?
Si c'est bien ça, il faut que tu prennes mon code entier, et pas juste la ligne 12.
Pour les cm, tu m'as seulement dit de mettre "m" pour bit96="10"... pas "cm" pour bit96="00".
Je le rajoute, et voici ce que tu dois exécuter :
A demain.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map /[\*\?]/ ? glob($_) : $_, @in; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier backup (l'ancien fichier d'entrée) en lecture # et le fichier de sortie en écriture (le nouveau fichier d'entrée) open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?,).*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say "$timestamp$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp$code"; } } } } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186 if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201 if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210 if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225 if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 74-50), undef, 0); # Decoder les bits 108 à 122 push @decoded, bin2hex(substr($bitcode, 107, 122-107), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 122 : 146, $bit82 eq "0" ? 138-122 : 162-146), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "00" ? "cm" : $bit96 eq "01" || $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }
non c'est 14 et 15 et non 15 et 16 , c'est peut etre la la petite difference.
Sinon pour cm c'était écris dans mon scénario, mais j'ai oublié de le redire aujourdhui, quand nous avons parlé de m
j'ai modifié moi meme et ca marche
merci infiniement Philou, ca marche super bien!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map /[\*\?]/ ? glob($_) : $_, @in; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier backup (l'ancien fichier d'entrée) en lecture # et le fichier de sortie en écriture (le nouveau fichier d'entrée) open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?,).*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say "$timestamp$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp$code"; } } } } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186 if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201 if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210 if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225 if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 74-50), undef, 0); # Decoder les bits 108 à 122 push @decoded, bin2hex(substr($bitcode, 107, 122-108), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 121 : 145, $bit82 eq "0" ? 137-122 : 161-146), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "00" ? "cm" : $bit96 eq "01" || $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }
il me reste une mini chose à faire mais je vais me débrouiller pour la réaliser
juste par rapport aux bits 95 96
si c'est 00 ca donne *10cm
01 cadonne * 1m
10 ca donne *10m,
j'avais du bien expliqué ce truc :S
J'ai fait ma nouvelle partie et ca marche presque
Si tu as des questions sur mon code, n'hésite pas : j'écris généralement comme je le fais pour tous mes programmes, sans tenir compte du niveau du programmeur qui l'utilisera. Certaines constructions peuvent être déroutantes pour un débutant en perl, mais c'est ainsi que je conçois que l'on apprend le mieux.
j'arrive plus bien à comprendre, parfois je dois adapter mon cerveau à la facon de penser mais ca va
merci beaucoup, moi qui ne puvait pas coder une ligne de ce langage il y a quelques semaines.
j'ai ajouté une étape à mon code, mais une chose me résiste:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map /[\*\?]/ ? glob($_) : $_, @in; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier backup (l'ancien fichier d'entrée) en lecture # et le fichier de sortie en écriture (le nouveau fichier d'entrée) open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?,).*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say "$timestamp$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp$code"; } } } } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186 if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201 if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210 if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225 if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 173, 1) eq "1" ? 177 : 171; push @decoded, bin2hex(substr($bitcode, 173, 177-171), undef, 0); } else { $bitpos = substr($bitcode, 187, 1) eq "1" ? 194 : 187; push @decoded, bin2hex(substr($bitcode, 187, 193-187), undef, 0); } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 196, 1) eq "1" ? 203 : 197; push @decoded, bin2hex(substr($bitcode, 197, 203-197), undef, 0); } else { $bitpos = substr($bitcode, 211, 1) eq "1" ? 218 : 212; push @decoded, bin2hex(substr($bitcode, 212, 218-212), undef, 0); } } # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 74-50), undef, 0); # Decoder les bits 108 à 122 push @decoded, bin2hex(substr($bitcode, 107, 122-108), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 121 : 145, $bit82 eq "0" ? 137-122 : 161-146), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "00" ? "cm" : $bit96 eq "01" || $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }dans cette partie, que j'ai codé moi meme, en reprenant modèle, j'ai obtenu le résultat que je souhaitais, mais je souhaite multiplier ce résultat par 5 .
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 173, 1) eq "1" ? 177 : 171; push @decoded, bin2hex(substr($bitcode, 173, 177-171), undef, 0); } else { $bitpos = substr($bitcode, 187, 1) eq "1" ? 194 : 187; push @decoded, bin2hex(substr($bitcode, 187, 193-187), undef, 0); } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 196, 1) eq "1" ? 203 : 197; push @decoded, bin2hex(substr($bitcode, 197, 203-197), undef, 0); }
j'ai voulu faire pareil que pour les metre et centimetres, mais j'ai pas obtenu de résultat concluant
Deux choses :
- tu calcules $bitpos (une position dans $bitcode) mais tu ne l'utilises pas ensuite
- où est ta multiplication par 5 ?
justement j'ai enlevé car ca ne marchait pas je pensais faire
push @decoded, ($bitpos* 5); mais ca m'a donné n'importe quoi
pour l'instant j'ai le décodage du bit pos sans sa multiplication
j'ai mismais ca me donne 855 pour une ligne exemple, alors que mon bit décodé me donne bien 27; qui fait 27*5= 135 et non pas 855
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 173, 1) eq "1" ? 177 : 171; #push @decoded, bin2hex(substr($bitcode, 173, 177-171), undef, 0); push @decoded, ($bitpos * 5); } else { $bitpos = substr($bitcode, 187, 1) eq "1" ? 194 : 187; #push @decoded, bin2hex(substr($bitcode, 187, 193-187), undef, 0); push @decoded, ($bitpos * 5); } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 196, 1) eq "1" ? 203 : 197; #push @decoded, bin2hex(substr($bitcode, 197, 203-197), undef, 0); push @decoded, ($bitpos * 5); } else { $bitpos = substr($bitcode, 211, 1) eq "1" ? 218 : 212; #push @decoded, bin2hex(substr($bitcode, 212, 218-212), undef, 0); push @decoded, ($bitpos * 5); } }
Je vais un peu me répéter : $bitpos contient une position (un numéro de bit, dont le premier est numéroté 0) dans $bitcode.
Pour obtenir une valeur numérique en utilisant $bitpos comme position du premier bit à décoder, tu dois appeler la fonction bin2hex avec les paramètres suivant :
- le code binaire sous forme ASCII (un substr de $bitcode, avec $bitpos comme premier paramètre et la taille du code en 2e paramètre)
- undef si le décodage se fait sur tous les bits, ou un nombre de bit s'il doit se faire par groupes de bits (codage binaire-décimal).
- 0 si LSB first ou 1 si MSB first
Ensuite seulement tu multiplies le résultat de bin2hex par 5.
Je me rends compte en expliquant que le nommage de la fonction bin2hex est mal choisi : il s'agirait plutôt de bin2dec (binary to decimal).
la je fais bien non ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 173, 1) eq "1" ? 177 : 171; push @decoded, bin2hex(substr($bitcode, 173, 177-171), undef, 0); push @decoded, ($bitpos * 5);
quelque chose ne va pas car je me retrouve avec deux valeurs
[CODE]avec ca je trouvais bien la valeur que je désirais
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 173, 1) eq "1" ? 177 : 171; push @decoded, bin2hex(substr($bitcode, 173, 177-171), undef, 0);
j'ai plus besoin de décoder pour faire * 5 ?
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager