QR Code for arbitrary data

May 18, 2012 at 11:00 AM
Edited May 18, 2012 at 11:02 AM

I'm working on a project that I need to encrypt the contents of the QR code.  I don't want just anyone with a phone to grab the QR code and read the contents in plain English.  The idea is that the iPhone app I'm writing will scan the QR code and then decrypt the message on the phone.

I've encrypted the ciphertext with AES-128 and want that data to form the QR code image.  Is there any way of forming a QR image from these arbitrary bytes?  While the WPF control is awesome, it only has a "Text" property.

Could you offer any advice?

By the way, I did try running the "Saving QR code to stream" example in the "Documents" section of your site.  The "Renderer" type does not seem valid.  I've included the following in my test application:

 

using Gma.QrCodeNet.Encoding.Windows.WPF;

 

Thanks for such a worthwhile and useful project!

Coordinator
May 20, 2012 at 4:27 AM

The solution that I will provide might not work, it depends on decoder at your iPhone part. It really rely on ECI(Extended channel interpretation) table. 

http://strokescribe.com/en/ECI.html

http://lab.must.or.kr/Default.aspx?Page=Extended-Channel-Interpretations-ECI-Encoding&NS=&AspxAutoDetectCookieSupport=1

QrCode and any barcode will follow ECI as for extended char table. Barcode will not take any byte input, but if you can translate byte to char then encode. That way will ensure you will get your info. 

Tricky thing at moment is to find a char table under ECI list that from 00 to FF will not have any empty value. Let me give you some example. 

Bad char table: iso-8859-1  http://en.wikipedia.org/wiki/ISO/IEC_8859-1    from 00~1F and some other area, they are empty. So when you translate 00 byte to 8859-1 table's char, it will gives you same char as byte 1E. Both byte on that table are blank. Depends on char decoder written within your language, they will most likely give a common char to represent those blank char. 

Good char table: IBM437 http://en.wikipedia.org/wiki/Code_page_437   As you can see, there is no blank byte. It's typical 00~FF one byte only char table. Problem is there is no such table include inside ECI list. However, google's zxing decoder and encoder list that table at number 0 and number 2. thus zxing's decoder surely able to decode that char table, then I'm not sure about other decoder, as I don't have their source code. 

For our encoder, we partly follow ECI list and adjust a bit according to ZXing. Our ECI list number 2 char table is IBM437. Encoder will detect it on it's own, so as long as your input string according to that will do. 

More detail about implementation will be, well if I am you I will do following. As you have byte set, translate byte set use IBM437 char table to proper string set, and pass that to encoder. At client side, decode, then use IBM437 to translate to byte. 

For C#, char table IBM437 is called as IBM437 while at Java, it's name is Cp437. 

 

Now for a way to solve issue that if decoder not support char table IBM437. That will involve some modify library action. Go to class file for ECISet.cs under folder DataEncodation folder. Remove "AppendECI("IBM437", 2, option);"  After remove that line and compile, now encoder won't check IBM437 table, it will use utf-8 char table. From what I know most of decoder support that. Progress will be same, at your side, translate byte to char use IBM437 same as before, then encode QrCode. Encoder will encode as utf8, at client side after decode, use IBM437 to translate that char string to byte. Now you have full byte array for you to use.

Disadvantage for that action will be utf8 char will use more byte than typical IBM437, thus QrCode sometime will be bigger than use first way to solve it. 

 

For renderer, I believe you didn't use 0.3 beta, instead, you choose to use latest source code. Am I right? If so, I would like you to check out following link. 

http://qrcodenet.codeplex.com/wikipage?title=User%20Controls&referringTitle=Documentation

After 0.3 beta, I have totally rewrite renderer and control, thus new control and renderer's commander are totally different to old one. I have written wiki for newest change under document, but didn't delete old one as we haven't officially publish next beta. Sorry about that. 

 

I hope that can help you solve your issue, let me know if you have any other questions. 

Also  if your byte array is huge, and use utf8 to solve that issue, then you need to have some knowledge about how many byte could version 40 QrCode contain. Break byte array to several pieces, making multiple QrCode according to that and combine them at client side. It will be a bit tricky. Check out ISO documentation we had at front page, scroll down to any table that could gives you that info will do. 

Coordinator
May 20, 2012 at 4:52 AM

OK, One more way to solve that issue. Maybe this is better than utf8. 

Issue with utf8 is that each char is no longer 8 bit. Thus it will take a lot of space. Another way to solve will be kanji. It will be hard, but space usage will be much lower and constant. 

Each kanji will be present as 13bit binary inside QrCode. Less than 2 byte and it's constant. Choose 255 kanji char and build your own char table. Translate byte array to kanji char then encode to QrCode, at client side, after receive kanji, use same table to get all byte. QrCode has special encode for Kanji, as it was originally develope by Japan. 

Kanji char's restriction, or I should say shift-jis char table's restriction I will write below. 

First, Kanji is not shift-jis, it's part of shift-jis table. Range from 8140 to 9FFC, and E040 to EBBF. (hex) Shift-jis value within that range we treat it as Kanji. Also, If you check each range, let's say 92??, Kanji doesn't fill out whole 255 space, it only from 9240 to 92FC, AND, there are also some blank space between 40, and FC. 

Shift-jis table: http://interscript.sourceforge.net/interscript/doc/en_shiftjis_0003.html

For range 92: http://interscript.sourceforge.net/interscript/doc/en_shiftjis_0023.html

From 40 to FC it has value, but double check 7F, it's blank. Thus when you create your own char table conversion, you need aware of that. If you bind part of char from 9240 to 92FC hex, it will go wrong, as there is no value at 7F. 

All in all, yea there is no way around, as QrCode and any barcode are design for char, not for byte.