Skip to content

Commit

Permalink
refactor: decode
Browse files Browse the repository at this point in the history
  • Loading branch information
xseman committed May 18, 2024
1 parent 55af265 commit 4982eca
Showing 1 changed file with 32 additions and 33 deletions.
65 changes: 32 additions & 33 deletions src/decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,21 @@ export function deserialize(qr: string): DataModel {
return output;
}

interface Header {
bysquareType: number;
version: number;
documentType: number;
reserved: number;
}

/**
* The function uses bit-shifting and masking to convert the first two bytes of
* the input header array into four nibbles representing the bysquare header
* values.
*
* @param header 2-bytes sie
*/
function bysquareHeaderDecoder(header: Uint8Array) {
function bysquareHeaderDecoder(header: Uint8Array): Header {
const bytes = (header[0] << 8) | header[1];
const bysquareType = bytes >> 12;
const version = (bytes >> 8) & 0b0000_1111;
Expand Down Expand Up @@ -197,16 +204,11 @@ export const parse = decode;
* @see 3.16.
*/
export function decode(qr: string): DataModel {
let bytes: Uint8Array | undefined;
try {
var bytes = base32hex.parse(qr, {
loose: true,
});
}
catch (error) {
throw new DecodeError(
error,
"Unable to decode QR string base32hex encoding",
);
bytes = base32hex.parse(qr, { loose: true });
} catch (error) {
throw new DecodeError(error, "Unable to decode QR string base32hex encoding");
}

const bysquareHeader = bytes.slice(0, 2);
Expand Down Expand Up @@ -244,10 +246,10 @@ export function decode(qr: string): DataModel {
...payload,
]);

let decompressed: string | Int8Array | undefined;
try {
var decompressed = decompress(body);
}
catch (error) {
decompressed = decompress(body);
} catch (error) {
throw new DecodeError(error, "LZMA decompression failed");
}

Expand All @@ -269,35 +271,32 @@ export function decode(qr: string): DataModel {
* not very reliable, there is room for improvement for the future.
*/
export function detect(qr: string): boolean {
let parsed: Uint8Array | undefined;
try {
var parsed = base32hex.parse(qr, {
loose: true,
});
}
catch {
throw new Error("Invalid data, Unable to decode base32hex QR string");
parsed = base32hex.parse(qr, { loose: true });
} catch {
return false;
}

if (parsed.byteLength < 2) {
return false;
}

const bysquareHeader = parsed.subarray(0, 2);
const {
bysquareType,
version,
documentType,
reserved,
} = bysquareHeaderDecoder(bysquareHeader);

const isValid = [bysquareType, version, documentType, reserved]
.every((nibble, index) => {
if (index === 1) {
return nibble <= Version["1.1.0"];
}
const header = bysquareHeaderDecoder(bysquareHeader);

const isValid = [
header.bysquareType,
header.version,
header.documentType,
header.reserved,
].every((nibble, index) => {
if (index === 1) {
return nibble <= Version["1.1.0"];
}

return 0x00 <= nibble && nibble <= 0x0F;
});
return 0x00 <= nibble && nibble <= 0x0F;
});

return isValid;
}

0 comments on commit 4982eca

Please sign in to comment.