- Ymox,
Bonjour à tous !
Je bidouille avec les QR codes ces temps. J’en suis au point où je tente de lire de manière binaire les données, que j’ai sous forme de matrice. A terme, j’aimerais pouvoir lire le(s) bit(s) ou octet(s) suivant(s) au clic sur l’un ou l’autre bouton.
L’algorithme de parcours n’est pas vraiment le problème (même s’il est certainement très naïf et sous-optimisé), c’est plus ma compréhension des générateurs en JavaScript qui doit être erronée, et leur utilisation peut-être incohérente.
Soit le code suivant.
Code de test
class QRcode {
version = 1;
matrix = [];
reader = null;
constructor (version) {
if (typeof version === 'undefined') {
version = 1;
}
this.version = version;
this.matrix = [
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
];
this.reader = this.readBit();
}
get size() {
return this.version * 4 + 16;
}
readBit = function* () {
console.log('start');
for (let column = this.size; column >= 0; column -= 2) {
const upwards = (((column / 2) % 2) == 0);
for (let row = (upwards ? this.size : 0); row >= 0 && row <= this.size; (upwards ? row-- : row++)) {
console.log(row, column, this.matrix[column][row]);
yield this.matrix[row][column];
console.log(row, column - 1, this.matrix[row][column - 1]);
yield this.matrix[row][column - 1];
}
}
console.log('end');
return;
}
readBits = function (bitNumber) {
const result = Array();
for (const bit of this.reader) {
console.log(bitNumber);
result.push(bit);
if (--bitNumber <= 0) break;
}
return result;
}
readOctet = function () {
let result = 0;
for (const bit of this.readBits(8)) {
result = (result << 1) | bit;
}
console.log(result);
return result.toString();
}
};
qrCode = new QRcode(1);
console.log(qrCode.readOctet(), qrCode.readOctet());
Ce que je ne comprends pas, c’est que ce code fournit comme résultat la sortie ci-après.
Sortie en console avec le code de test ci-avant
start L42:11
20 20 1 L46:13
8 L58:12
20 19 0 L48:13
7 L58:12
19 20 0 L46:13
6 L58:12
19 19 1 L48:13
5 L58:12
18 20 0 L46:13
4 L58:12
18 19 0 L48:13
3 L58:12
17 20 0 L46:13
2 L58:12
17 19 1 L48:13
1 L58:12
179 L69:11
0 L69:11
179 0 L74:9
Je constate que le générateur n’est pas du tout utilisé alors que je m’attendrais à avoir la sortie de débogage correspondant à la lecture du second octet.
Si, plutôt que de mettre le générateur dans une propriété de la classe, j’utilise ligne 57 directement la méthode readBit()
, j’ai bien deux sorties de lecture, mais c’est toujours le premier octet — une logique que je peux comprendre.
Apparemment, ma méthode QRcode.readBit()
n’est pas directement le générateur, mais un constructeur pour celui-ci. Du coup, je suis en train de m’embrouiller.
- Y a-t’il moyen d’éviter cette propriété pour l’instance du générateur, donc faire en sorte que
readBit()
soit le générateur ? Serait-ce juste une question de syntaxe ? - Afin de pouvoir lire un nombre arbitraire de bits à la fois, mais en séquence, est-ce que ma méthode
readBits()
doit elle aussi être un générateur ? Le cas échéant, je n’arrive pas à voir les transformations nécessaires.
La question sera similaire pourreadOctet()
et une méthode à venirreadOctets()
.
Merci d’avance