smart-on-fhir / health-cards

Health Cards Framework: implementation guide and supporting material
Other
259 stars 84 forks source link

specify version 22 #186

Open jhcao23 opened 2 years ago

jhcao23 commented 2 years ago

Can we specify the version is 22? { type: 'svg', errorCorrectionLevel: 'low', version: 22 } https://github.com/smart-on-fhir/health-cards/blob/364a00106ce857131b2bd560273e74263777a909/generate-examples/src/index.ts#L206

jmandel commented 2 years ago

Can you say more about the motivation for this? One challenge is that adding an explicit version would cause us to produce denser codes than are needed (e.g., if the information fits in a V20 symbol, it's undesirable to produce a V22 symbol).

jmandel commented 2 years ago

(See background at https://github.com/dvci/health-cards-walkthrough/issues/4)

jhcao23 commented 2 years ago

hi @jmandel the reason I mention this v22 is the original spec at chunking section. Here is the quote:

Commonly, Health Cards will fit in a single V22 QR code. Any JWS longer than 1195 characters SHALL be split into "chunks" of length 1191 or smaller; each chunk SHALL be encoded as a separate QR code of V22 or lower, to ensure ease of scanning.

I'm not an expert of raw qrcode concept, however I agree with you that V22 should be an upper bound but I assume the default version of node qrcode is the latest edition v40 maybe?

p2-apple commented 2 years ago

You're right, v22 is an upper bound, which we tried to call out with this sentence:

each chunk SHALL be encoded as a separate QR code of V22 or lower

We could provide more guidance here. Most implementations use the default error correction level and see which QR version this fits in. Only once you start bumping against v22 you should consider lowering the error correction level.

jhcao23 commented 2 years ago

@p2-apple Don't we prefer high error correction level when qr version is fixed?

My understanding is this routine:

You're right, v22 is an upper bound, which we tried to call out with this sentence:

each chunk SHALL be encoded as a separate QR code of V22 or lower

We could provide more guidance here. Most implementations use the default error correction level and see which QR version this fits in. Only once you start bumping against v22 you should consider lowering the error correction level.

p2-apple commented 2 years ago

Don't we prefer high error correction level when qr version is fixed?

It depends a lot on what the QR code is used for. These levels are more important for physical reproductions of QR codes (i.e. printed somewhere) where the print may degrade (e.g. crumpled paper, abrasions). The higher two levels Q and H are generally only necessary when it is expected that the code will be damaged, the lower two (L and M) can correct for less damage. So, you only need to bump up error correction when you actually expect damage to a QR code, for codes shown on e.g. a phone screen with a high enough resolution that is not necessary. The algorithm I would propose:

radamson commented 2 years ago

It might not belong in the spec itself, but would it be helpful to record how the 1195 JWS character limit was determined along with guidance for capacities supported at other error correction level in a wiki or FAQ?

I know I've seen it before, but I couldn't find it here or on Zulip so I attempted to go through it again here:

JWS Characters for V22 QR at Various Error Correction Levels

A single, non-chunked Version 22 SMART Health Card QR contains two segments * The first Byte mode segment (`shc:/`) always has 20 header bits and 40 data bits for a total of 60 bits.[1](https://www.nayuki.io/page/optimal-text-segmentation-for-qr-codes) * The second segment (the numeric encoded QR code) always has 16 header bits and a variable number of data bits depending on the QR code length.[1](https://www.nayuki.io/page/optimal-text-segmentation-for-qr-codes) The max JWS size that can fit in a single Version 22 QR code depends on the remaining space, which depends on the error correction used. 76 bits are already reserved for the required segment headers and `shc:/` prefix. The following table lists the total number of bits a Version 22 QR Code can contain. | Error Correction Level | Total data bits for V22 QR | | ------------- | ------------- | | Low | 8048 | | Medium | 6256 | | Quartile | 4544 | | High | 3536 | [2 (Table Source)](https://www.qrcode.com/en/about/version.html) Each JWS character is encoded into two numeric characters (As described in [Encoding Chunks as QR codes](https://spec.smarthealth.cards/#encoding-chunks-as-qr-codes)) and each numeric character requires 20/6 bits.[1](https://www.nayuki.io/page/optimal-text-segmentation-for-qr-codes) Thus we can determine the maximum JWS size for each error correction with the following: JWS Size = ((Total Data Bits - 76 bits reserved) * 6/20 bits per numeric character * 1/2 JWS character per numeric character = (Total Data Bits - 76)*3/20 The results of the above rounded down to the nearest integer number of characters gives: | Error Correction Level | Max JWS Length for V22 QR | | ------------- | ------------- | | Low | 1195 | | Medium | 927 | | Quartile | 670 | | High | 519 | **References:** 1. [Project Nayuki: Optimal text segmentation for QR Codes](https://www.nayuki.io/page/optimal-text-segmentation-for-qr-codes) 2. [QR Code capacities](https://www.qrcode.com/en/about/version.html) @jmandel where did I mess up 🙂 ?
jmandel commented 2 years ago

This looks great -- Mayne let's record it as a file in the FAQ directory, and we can link to it from the spec?