This qr code generator can store only 20 caracters for now (it's the smallest qr code size), also, it's not optimized for now, I'm not satisfied of some parts, especially the one where the program place the squares.
You can see it in action at youtube address Su0MpwFSWFE
I'll fisrt explain quickly how to make a qr code:
Firstly, you choose with which text type (kanji, numeric, etc) you're gonna encode the data (here, it's always alphanumeric : numbers and uppercase letters).
Secondly, you encode text in binary following the step matching the text type.
Thirdly, you generate the error correction codewords (that's the difficult part), basically (if I understand well), you divide two equations in a galois field (one is generate with your data string, the other depends on your qr size and error correction level), there are 4 level of correction (L, M, Q and H) here I use level M.
Fourth, you put the error codewords after your binary data string from before (it's different for larger qr code, though)
Fifth, you place the string in your matrix (black square for 1 and white square for 0)
Sixth, you "mask" some squares (it mean changing it's color by the opposite), there are 8 masking pattern, you are supposed to choose the optimal one (here I use only the mask pattern 1)
Last, you add the format string, which correspond to your error correction level and your mask pattern
I divided the entire program in 6 progams.
prgmMAIN
:AxesOff
:FnOff
:ZInteger
:{0}→LC
:"0010"→Str2 //Str2 will be the data string, 0010 is the code for alphanumeric
:ClrDraw
:Input "SENTENCE:",Str1
:Text(1,1,"ANALYSING DATA")
:For(J,1,length(Str1))
:For(I,1,44)
:If sub(Str1,J,1)=sub("123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ?θ*+-./:",I,1)
:Then
:I→L1(J) //the rank of the character is it's "code" in alphanumeric
:End
:If sub(Str1,J,1)="0"
:Then
:0→L1(J)
:End
:End
:End
:length(Str1)→B
:prgmBIN //This program turn numbers into binary and add them to the data string
:If length(Str1)>20
:Then
:Disp "YOUR SENTENCE IS TOO LONG"
:Stop
:Else
:{0,251,67,46,61,118,70,64,94,32,45}→LA
:End
:Text(1,1,"ENCODING DATA")
:If length(Str1)/2=int(length(Str1)/2)
:Then
:For(J,1,dim(L1),2)
:(L1(J)*45)+L1(J+1)→ B
:prgmBIN
:End
:Else
:For(J,1,dim(L1)-1,2)
:(L1(J)*45)+L1(J+1)→ B
:prgmBIN
:End
:L1(dim(L1))→B
:B→C
:prgmBIN
:End
:While length(Str2)/8≠int(length(Str2)/8)
:Str2+"0"→Str2
:End
:While length(Str2)≠128 // the data string must be 128 bits long, if it's not, we must add these strings
:Str2+"11101100"→Str2
:If length(Str2)≠128
:Then
:Str2+"00010001"→Str2
:End
:End
:prgmERROR1 //this program generate two list with numbers from 0 to 255 and their equivalent in power of 2 (in galois field)
:0→B
:1→N
:For(I,128,8,-8
:For (J,I,I-7,-1)
:If sub(Str2,J,1)="1"
:Then
:B+2^(I-J)→B
:End
:End
:B→LC(N)
:0→B
:N+1→N
:End
:dim(LC→M
:For(L,1,int(M/2
:LC(L→Z
:LC(M-L+1→LC(L
:Z→LC(M-L+1
:End
:For(K,1,16)
:prgmERROR2 // this program generate the error codeword and place them in LC list
:End
:ClrListLANTI
:ClrListLLOG
:For(J,2,dim(LC)
:LC(J)→B
:prgmBIN
:End
:PrgmTEST //This one place the data string in the matrix
pgrmBIN :
:1→N
:{0}→L2
:While B≠0
:If B/2=int(B/2)
:Then
:0→L2(N)
:Else
:1→L2(N)
:End
:N+1→N
:int(B/2)→B
:End
:If length(Str2)=4 //numbers must be encoded in several bit size, so I put several conditions
:Then
:While dim(L2)≠9
:0→L2(dim(L2)+1
:End
:Else
:If L1(dim(L1))=C
:Then
:While dim(L2)≠6
:0→L2(dim(L2)+1)
:End
:Else
:If dim(LC)>1
:Then
:While dim(L2)≠8
:0→L2(dim(L2)+1)
:End
:Else
:While dim(L2)≠11
:0→L2(dim(L2)+1)
:End
:End
:End
:End
:dim(L2→M
:For(L,1,int(M/2
:L2(L→Z
:L2(M-L+1→L2(L
:Z→L2(M-L+1
:End
:45→C
:"?
:For(I,1,dim(L2
:Ans+sub("01",1+L2(I),1
:End
:Str2+sub(Ans,2,length(Ans)-1→Str2
PrgmERROR :
:For(J,1,dim(LC))
:1 → N
:{0}→L5
:{0}→L6
:{0}→L1
:While L4(J)≠0
:If L4(J)/2=int(L4(J)/2)
:Then
:0→L5(N)
:Else
:1→L5(N)
:End
:N+1→N
:int(L4(J)/2)→L4(J)
:End
:1→N
:While LC(J)≠0
:If LC(J)/2=int(LC(J)/2)
:Then
:0→L6(N)
:Else
:1→L6(N)
:End
:N+1→N
:int(LC(J)/2)→LC(J)
:End
:While dim(L6)≠dim(L5)
:If dim(L6)>dim(L5)
:0→L5(dim(L5)+1)
:Else
:0→L6(dim(L6)+1)
:End
:End
:For(I,1,dim(L5))
:If L5(I)=L6(I)
:Then
:0→L1(I)
:Else
:1→L1(I)
:End
:End
:0→B
:For(I,1,dim(L1))
:If L1(I)=1
:Then
:B+2^(I-1)→B
:End
:End
:B→LC(J)
:End
prgm ERROR1:
:ClrDraw
:Text(1,1,"GENERATING:")
:Text(7,1,"POWERS OF 2")
:For(I,0,255)
:I→LLOG(I+1)
:End
:{256}→LC
:{1,2,4,8,16,32,64,128}→LANTI
:Text(7,1,"POWERS OF 2 IN GALOIS FIELD")
:For(K,9,256)
:If LC(1)>255
:Then
:LC → L4
:{285} → LC
:prgmERROR //This program "Xor" numbers (it take their binary form and add them modulo 2)
:End
:LC(1)→ LANTI(K)
:LC(1)*2 → LC(1)
:End
PrgmERROR2:
:ClrList L4
:ClrDraw
:Text(1,1,"GENERATING:")
:Text(7,1,"ERROR CODE",K)
:If K>1
:Then
:For(I,2,dim(LC))
:LC(I)→LC(I-1)
:End
:dim(LC)-1 → dim(LC)
:End
:For(I,1,dim(LANTI))
:If LANTI(I)=LC(1)
:Then
:LLOG(I) → P
:dim(LANTI)+1 → I
:End
:End
:For(I,1,dim(LA))
:If P+LA(I)>255
:Then
:remainder(P+LA(I),255 → L4(I))
:Else
:P+LA(I) →L4(I)
:End
:End
:For(I,1,dim(L4))
:For(J,1,dim(LLOG))
:If LLOG(J)=L4(I)
:Then
:LANTI(J)→B
:End
:End
:B→L4(I)
:End
:While dim(L4)≠dim(LC)
:If dim(L4)<dim(LC)
:Then
:0→L4(dim(L4)+1)
:Else
:0→LC(dim(LC)+1)
:End
:End
:ClrDraw
:Text(1,1,"XORING CODE",K)
:prgmERROR
PrgmTEST :
:41→A
:30→B
:1→K
:ZInteger
:ClrDraw
:RecallPic Pic2 //here is stored the basic image for qr codes
:For(D,56,37,-2) //D is the collumn
:For(J,A,B,-1) //J is the row
:If J=27
:Then
:J-1→J
:End
:If sub(Str2,K,1)="1"
:Then
:Pxl-On(J,D)
:End
:If remainder(J+1,2)=0
:Then
:Pxl-Change(J,D)
:End
:If sub(Str2,K+1,1)="1"
:Then
:Pxl-On(J,D-1)
:End
:If remainder(J+1,2)=0
:Then
:Pxl-Change(J,D-1)
:End
:K+2→K
:End
:D-2→D
:If D=42
:Then
:D-1→D
:End
:For(J,B,A)
:If J=27
:Then
:J+1→J
:End
:If sub(Str2,K,1)="1"
:Then
:Pxl-On(J,D)
:End
:If remainder(J+1,2)=0
:Then
:Pxl-Change(J,D)
:End
:If sub(Str2,K+1,1)="1"
:Then
:Pxl-On(J,D-1)
:End
:If remainder(J+1,2)=0
:Then
:Pxl-Change(J,D-1)
:End
:K+2→K
:End
:If D=50
:Then
:B-9→B
:End
:If D=46
:Then
:B+9→B
:A-8→A
:End
:End
:"101000100100101"->Str3
:29→J
:36→D
:For(K,1,8)
:If D=42
:Then
:D+1→D
:End
:If sub(Str3,K,1)="1"
:Then
:Pxl-On(J,D)
:End
:D+1→D
:End
:44→D
:28→J
:For(K,9,15)
:If J=27
:Then
:J-1→J
:End
:If sub(Str3,K,1)="1"
:Then
:Pxl-On(J,D)
:End
:J-1→J
:End
:44→D
:1→K
:For(J,41,35,-1)
:If sub(Str3,K,1)="1"
:Then
:Pxl-On(J,D)
:End
:K+1→K
:End
:29→J
:8→K
:For(D,49,56)
:If sub(Str3,K,1)="1
:Then
:Pxl-On(J,D)
:End
:K+1→K
:End
Posts merged and formatted by a moderator