- From: Ed Eykholt <ed.eykholt@gmail.com>
- Date: Fri, 14 Feb 2020 12:34:53 -0800
- To: Christopher Allen <ChristopherA@lifewithalacrity.com>
- Cc: W3C DID Working Group <public-did-wg@w3.org>, Credentials Community Group <public-credentials@w3.org>, Wolf McNally <wolf@wolfmcnally.com>, Ryan Grant <rgrant@rgrant.org>
- Message-ID: <CAH2D2U9MN686dEKJ98on2a2MEeXJbu3k+EuozaDgwA5eWob7KQ@mail.gmail.com>
I have the need to print a QR code of a VC on a document. I want it to have high a error-correction factor. If a VC were to be translated into an abbreviated form, this would help with the size and density. The minimum content might include a pointer to the schema (assuming it is published on a public blockchain or other location) and then encoding all the values with protobuf, then some binary encoding over the whole thing. After reading such a QR code with a client application, it could be re-hydrated (assuming an internet connection to the schema or a cache of it) back into the compliant JSON VC. On Fri, Feb 14, 2020 at 12:23 PM Christopher Allen < ChristopherA@lifewithalacrity.com> wrote: > (To the DID and CCG lists. Please keep the cc: to Wolf if you want him to > reply to any questions) > > Blockchain Commons has a goal to be able to DID documents and VCs > leveraging airgap QR Codes, and asked Wolf do to some research for me. > > This research came from a comment by Ryan Grant <rgrant@rgrant.org>: > > > The reason I ask about side of diddoc is that the brace characters are > not in the qrcode alphanumeric alphabet. The iphone qrcode will only > reliably read 2953 binary bytes. I think the most interoperabe qrcode > encoding of the diddoc will be base64, which means the limit on an iphone > reader is 2214 bytes. > > The result from Wolf McNally <wolf@wolfmcnally.com> is: > > > I conclude from these experiments that there is unlikely to be any great > benefit from first transcoding a JSON document to a less dense character > set in order to activate a more dense QR encoding. > > > I hope you find this helpful. > > Some longer-term questions we have are to do with what to do when we do > exceed the limits of a single QR code. For instance, we've considering > proposing something like this wrapper in QR codes that are multipart and > need to be animated. We have seen a business-card-sized device (the SafePal > bitcoin wallet https://safepal.io/ ) with a camera and small screen that > can do animated QR codes, so we know this is feasible on low-powered > hardware: > > ``` > { > "header": { > "format": "Airgap", > "version": 1 > }, > "multiPart": { > "uid": "449C40FE-E207-4AC9-B552-51B007B68D50", > "part": 0, > "count": 1, > "data": "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4K" > } > } > ``` > > We have also found that QR code size limits are smaller when using a > camera on a laptop because of lack of closeup focus. Does anyone have any > experience with this? > > Any other thoughts, advice, questions on using QR codes with DIDs and VCs? > > — Christopher Allen > > > ---------- Forwarded message --------- > From: Wolf McNally <wolf@wolfmcnally.com> > Date: Fri, Feb 14, 2020 at 1:15 AM > Subject: QR Code Density Comparison > To: Christopher Allen <christophera@lifewithalacrity.com> > > > *QR Code Density Comparison* > > This is a comparison of various encodings of a piece of JSON text, with > the goal of determining whether the QR Code generation algorithm in iOS > selects an encoding mode (binary vs. alphanumeric) automatically, and > whether it makes sense to pre-encode the JSON in some other format that > will be more efficiently encoded by the QR Code generator. > > All QR encodings in the document use the Low Error Correction option. > > Text 1 below is a default DID document. When QR encoded, the resulting > image is 91x91 modules (8,281 modules total) > > Text 1 (639 characters): > > { "@context": "https://w3id.org/did/v0.11", > "id": "did:btcr:xsdv-zrtp-qe4h-vga", > "publicKey": [ { > "id": "did:btcr:xsdv-zrtp-qe4h-vga#satoshi", > "controller": "did:btcr:xsdv-zrtp-qe4h-vga", > "type": "EcdsaSecp256k1VerificationKey2019", > "publicKeyBase58": "22zj7sFEsYQXcvLFV55Z4oA6yQZwwKGPa893D8V3EnipS" > }, { > "id": "did:btcr:xsdv-zrtp-qe4h-vga#vckey-0", > "controller": "did:btcr:xsdv-zrtp-qe4h-vga", > "type": "EcdsaSecp256k1VerificationKey2019", > "publicKeyBase58": "22zj7sFEsYQXcvLFV55Z4oA6yQZwwKGPa893D8V3EnipS" > } ], > "authentication": ["#satoshi"], > "assertionMethod": ["#vckey-0"] } > > Text 1 encoded (91x91 modules): > > > ———————— > > Text 2 consists of the same number of characters as Text 1, but drawn from > the QR Code alphanumeric set, excluding space. This consists of the 43 > characters: > > 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ$%*-./: > > Table of Alphanumeric Values - QR Code Tutorial > <https://www.thonky.com/qr-code-tutorial/alphanumeric-table> > > The result of QR encoding this text is an image that consists of only > 75x75 modules = 5,625 modules, which is about 30% smaller than Text 1. From > this we conclude that the QR code generator is auto-detecting whether the > input string can be encoded using the alphanumeric mode and switching to it > if possible. > > Text 2 (639 random characters in A...Z): > > > /FBMCUE$1K/67DXM:$HTT5H46KSN4$N$EK2J7B0GA3RL8IXZ%B*%R9M7HCS*UB199-S5-2*M:*PZ42698MA/D4TK4:7B*011RKLDN085D53G$M.-U9*YFXE.*CCBM49DPJFXK%2C$QYBMLJCAG.HJTJ7ZQWS.WH0PN%MEMN/2B-$8L8F4CKOYML4M4PQTZS17A9.Z.HWBRRMGISTI%V1*NB/DVTT*R*..GF58UM%::OW1G$65ZIGQR38T16A-LJHHAJNI8C3/J2AYXBAC-DMMJNUKS:.GK3D08-$*62UTEK..8Q8:VE3UTXJMC:U:$7*IVX:VN924JENFBLWDKR1CN$%RG24T4J5GKHD9RK7MVO2JYAH0KDLSOEF:*M1AJ/28*QG6HEQ48:TGQJTX73/44C%ON6C:I31DIU:BC52YXS83NZ-.XZULG:0XAYPM/LJC9C/3GLJ285W*$-W5SP337/*$*JOH.S$OGJ6KZ8YZTY/2ZWLDO3YNLGI4HD3I/7AM7B*.O9K8SZUB*CJCX.UEKRG-$R%4ZI8MBIUG2ONFU%RL1Y::CVMYI6K7N6%F65FEQQ/X40ND/LNX-ASZ60DF-B3*N$AQU2UO*$UNHUS*W0HBH/W6:VZC:Y6%M30KJN1H > > Text 2 encoded (75x75 modules): > > > ———————— > > To begin to test alternate encodings, we encode Text 1 using Base-64 and > then QR encode that. The result is an image that is 103x103 modules = > 10,609 modules, whch is almost 30% *larger* than the encoded form of Text > 1. Obviously Base-64 uses characters not in the QR code's alphanumeric set, > so the encoding must take place in binary mode. > > Text 3 (Text 1 base 64 encoded, 852 characters): > > > eyAiQGNvbnRleHQiOiAiaHR0cHM6Ly93M2lkLm9yZy9kaWQvdjAuMTEiLAogICJpZCI6ICJkaWQ6YnRjcjp4c2R2LXpydHAtcWU0aC12Z2EiLAogICJwdWJsaWNLZXkiOiBbIHsKICAgICAgImlkIjogImRpZDpidGNyOnhzZHYtenJ0cC1xZTRoLXZnYSNzYXRvc2hpIiwKICAgICAgImNvbnRyb2xsZXIiOiAiZGlkOmJ0Y3I6eHNkdi16cnRwLXFlNGgtdmdhIiwKICAgICAgInR5cGUiOiAiRWNkc2FTZWNwMjU2azFWZXJpZmljYXRpb25LZXkyMDE5IiwKICAgICAgInB1YmxpY0tleUJhc2U1OCI6ICIyMnpqN3NGRXNZUVhjdkxGVjU1WjRvQTZ5UVp3d0tHUGE4OTNEOFYzRW5pcFMiCiAgICB9LCB7CiAgICAgICJpZCI6ICJkaWQ6YnRjcjp4c2R2LXpydHAtcWU0aC12Z2EjdmNrZXktMCIsCiAgICAgICJjb250cm9sbGVyIjogImRpZDpidGNyOnhzZHYtenJ0cC1xZTRoLXZnYSIsCiAgICAgICJ0eXBlIjogIkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSIsCiAgICAgICJwdWJsaWNLZXlCYXNlNTgiOiAiMjJ6ajdzRkVzWVFYY3ZMRlY1NVo0b0E2eVFad3dLR1BhODkzRDhWM0VuaXBTIgogIH0gXSwKICAiYXV0aGVudGljYXRpb24iOiBbIiNzYXRvc2hpIl0sCiAgImFzc2VydGlvbk1ldGhvZCI6IFsiI3Zja2V5LTAiXSB9 > > Text 3 encoded (103x103 modules): > > > ———————— > > Next we encode Text 1 using Base-32. The resulting QR code is 91x91 > modules = 8,281 modules. This is the same size QR code generated for the > original Text 1, thus in this case we gain no advantage from the extra > encoding step. > > Text 4 (Text 1 base 32 encoded RFC 4648, 1024 characters): > > > PMQCEQDDN5XHIZLYOQRDUIBCNB2HI4DTHIXS65ZTNFSC433SM4XWI2LEF53DALRRGERCYCRAEARGSZBCHIQCEZDJMQ5GE5DDOI5HQ43EOYWXU4TUOAWXCZJUNAWXMZ3BEIWAUIBAEJYHKYTMNFRUWZLZEI5CAWZAPMFCAIBAEAQCAITJMQRDUIBCMRUWIOTCORRXEOTYONSHMLL2OJ2HALLRMU2GQLLWM5QSG43BORXXG2DJEIWAUIBAEAQCAIBCMNXW45DSN5WGYZLSEI5CAITENFSDUYTUMNZDU6DTMR3C26TSORYC24LFGRUC25THMERCYCRAEAQCAIBAEJ2HS4DFEI5CAISFMNSHGYKTMVRXAMRVGZVTCVTFOJUWM2LDMF2GS33OJNSXSMRQGE4SELAKEAQCAIBAEARHA5LCNRUWGS3FPFBGC43FGU4CEORAEIZDE6TKG5ZUMRLTLFIVQY3WJRDFMNJVLI2G6QJWPFIVU53XJNDVAYJYHEZUIOCWGNCW42LQKMRAUIBAEAQH2LBAPMFCAIBAEAQCAITJMQRDUIBCMRUWIOTCORRXEOTYONSHMLL2OJ2HALLRMU2GQLLWM5QSG5TDNNSXSLJQEIWAUIBAEAQCAIBCMNXW45DSN5WGYZLSEI5CAITENFSDUYTUMNZDU6DTMR3C26TSORYC24LFGRUC25THMERCYCRAEAQCAIBAEJ2HS4DFEI5CAISFMNSHGYKTMVRXAMRVGZVTCVTFOJUWM2LDMF2GS33OJNSXSMRQGE4SELAKEAQCAIBAEARHA5LCNRUWGS3FPFBGC43FGU4CEORAEIZDE6TKG5ZUMRLTLFIVQY3WJRDFMNJVLI2G6QJWPFIVU53XJNDVAYJYHEZUIOCWGNCW42LQKMRAUIBAPUQF2LAKEAQCEYLVORUGK3TUNFRWC5DJN5XCEORALMRCG43BORXXG2DJEJOSYCRAEARGC43TMVZHI2LPNZGWK5DIN5SCEORALMRCG5TDNNSXSLJQEJOSA7I= > > Text 4 encoded (91x91 modules): > > > ———————— > > A hypothetical Base43 converter would fully utilize the bandwidth > available in the QR code alphanumeric character set. We can estimate the > number of characters needed for the 639 characters of text 1: > > 639 characters * 8 bits/character = 5,112 bits > Number of bits encoded in a single QR code alphanumeric encoder: > Solve[2^n == 43, n, Reals] // N > {{n → 5.42626}} > 5,112 bits / 5.42626 bits/character = 942 characters > > Generating another random 942 characters from the QR code character set to > simulate the output of the hypothetical Base54 converter, we get Text 5. QR > encoding text 5 again gives us a QR code that is 91x91 modules— the same > size as the Base32 encoded Text 4. > > Text 5 > > > U8BDDGI7/8NBETWBLB3FC.-/O.6OCHDT0H.00QOC5T4/B-CP4C7$GZOYD*.-SISN72XXJTLIDJ5C-*X:3:D57A4*NOZI8AMCV75D.2N5KNFBL-ZZ1PC/RUOXGLSD1HIF8:AT8.KIROQ9G-$.T6MZG:4K2CA-JKNGJGY8V60X5R% > QGQQXN10383.CO > %7OSYAGJE:RD:3LI4K:LHQYNEJ5$SXYGN0PF53F9MC3TN31WTL:CU1D83G1XWZVCHIKO.VKA9CLIK$JXIFO0AD6XDVK4SS37E60*SOUM/1R$T-TJEU9AW4DBK2NE:WIR8$EGHRU%*91UAEG0D48R75-048/711V8:M2XLSW0%96RJGN4P36HI-LF1MT24P:L/D6W00D5:FK18K8FIQ0PTAO:%-XY.7UAD/XRKC3RPLDA0MC9UNT3W*.ZRQHNZKZ%Z$3OP8O--28543TRQTV$BK6JI2SB3Y5V$S9OCER400AQQ%61WR07VFU/WSM99$$HBKD/4HY7KFY4LMHTLC-BGU1$8M39O3-NB%64LFKYS8VB1VVOM1O5QW-SE*U0VTR:I.0WO:*WONDT664E/0NOJMYMGW/SS-*/AMR5FO-2P9UKNGYQ43.LIY03*PSFUB6FAWZRB/X9H6FGN$/6OZP/Y$K:DXRIM0FS3532B/$9*:I2YN%1RN.7CIRH7R7:A6%D::Z8.6YN.*38DQ%0QGAI:2MHV8-SC75LWWEXZQ9VPESQO24AI**1KEZ70G1K9-XFZX1JSAJOMYE66WJZ/WMAX2DP26*UBLTV2OO3J77D5BUPD7AX1-W8F/AW65HHXLT2V*Z:QKY-Q*MKETR76G*/GV58L9::-KB2MMEDQN5OF0:E2FVI%V0D*OBMJW9OR-SW/U%PM2$$JZ05Q/JK0YVYB2W3LSSFP2P/1TWY5$8/E*O*6F5U0Z%5C > > Text 5 encoded (91x91 modules): > > [image: QR Code 5.png] > > ———————— > > I conclude from these experiments that there is unlikely to be any great > benefit from first transcoding a JSON document to a less dense character > set in order to activate a more dense QR encoding. The alphanumeric mode of > QR codes is clearly suited to text that can be expressed in its original > form in the particular alphanumeric character set. JSON requires characters > that are not in the QR code alphanumeric set, like the curly braces, and > even its alphabetical components (key names and values) are case sensitive. > If an encoding other than JSON were designed that only used characters from > the QR code alphanumeric set, then it is possible that greater efficiency > could be achieved. But a general scheme would still need to encode > case-preserving strings such as user-entered data, and this data would > still have to be transcoded field by field before the whole data structure > could be QR encoded. > > My recommendation is that further attempts to use only the QR code > alphanumeric mode be set aside as premature optimization requiring > considerable work for uncertain gain. > > 🐺 > >
Attachments
- image/png attachment: QR_Code_1.png
- image/png attachment: QR_Code_2.png
- image/png attachment: QR_Code_3.png
- image/png attachment: QR_Code_4.png
- image/png attachment: QR_Code_5.png
Received on Sunday, 16 February 2020 02:13:49 UTC