#include <stdio.h>
#include <stdlib.h>
#include "definition.h"
#include <math.h>
#include <string.h>
unsigned int calalign_n(int ver) //计算校正图形数,同时为校正图形坐标赋值
{
if(ver==1) return 0;
if(ver>1&&ver<=6) return 1;
if(ver>6&&ver<=13) return 6;
if(ver>13&&ver<=20) return 13;
if(ver>20&&ver<=27) return 22;
if(ver>27&&ver<=34) return 33;
if(ver>34&&ver<=40) return 46;
else return -1;
}
void getalign_coord(Qrcodeinfo* qrcode,int ver)
{
if(ver>=1) qrcode->align_coord[0]=6;
if(ver>1&&ver<=6) qrcode->align_coord[1]=10+4*ver;
if(ver>=7&&ver<=13)
{
qrcode->align_coord[1]=8+2*ver;
qrcode->align_coord[2]=10+4*ver;
}
if(ver>=14&&ver<=16)
{
qrcode->align_coord[1]=26;
qrcode->align_coord[2]=46+2*(ver-14);
qrcode->align_coord[3]=66+4*(ver-14);
}
if(ver>=17&&ver<=19)
{
qrcode->align_coord[1]=30;
qrcode->align_coord[2]=54+2*(ver-17);
qrcode->align_coord[3]=78+4*(ver-17);
}
if(ver==20)
{
qrcode->align_coord[1]=34;
qrcode->align_coord[2]=62;
qrcode->align_coord[3]=90;
}
if(ver>=21&&ver<=27)
qrcode->align_coord[4]=94+4*(ver-21);
if(ver==21)
{
qrcode->align_coord[1]=28;
qrcode->align_coord[2]=50;
qrcode->align_coord[3]=72;
}
if(ver==22)
{
qrcode->align_coord[1]=26;
qrcode->align_coord[2]=50;
qrcode->align_coord[3]=74;
}
if(ver==23)
{
qrcode->align_coord[1]=30;
qrcode->align_coord[2]=54;
qrcode->align_coord[3]=78;
}
if(ver==24)
{
qrcode->align_coord[1]=28;
qrcode->align_coord[2]=54;
qrcode->align_coord[3]=80;
}
if(ver==25)
{
qrcode->align_coord[1]=32;
qrcode->align_coord[2]=58;
qrcode->align_coord[3]=84;
}
if(ver==26)
{
qrcode->align_coord[1]=30;
qrcode->align_coord[2]=58;
qrcode->align_coord[3]=86;
}
if(ver==27)
{
qrcode->align_coord[1]=34;
qrcode->align_coord[2]=62;
qrcode->align_coord[3]=90;
}
if(ver>=28&&ver<=34)
qrcode->align_coord[5]=122+4*(ver-28);
if(ver==28)
{
qrcode->align_coord[1]=26;
qrcode->align_coord[2]=50;
qrcode->align_coord[3]=74;
qrcode->align_coord[4]=98;
}
if(ver==29)
{
qrcode->align_coord[1]=30;
qrcode->align_coord[2]=54;
qrcode->align_coord[3]=78;
qrcode->align_coord[4]=102;
}
if(ver==30)
{
qrcode->align_coord[1]=26;
qrcode->align_coord[2]=52;
qrcode->align_coord[3]=78;
qrcode->align_coord[4]=104;
}
if(ver==31)
{
qrcode->align_coord[1]=30;
qrcode->align_coord[2]=56;
qrcode->align_coord[3]=82;
qrcode->align_coord[4]=108;
}
if(ver==32)
{
qrcode->align_coord[1]=34;
qrcode->align_coord[2]=60;
qrcode->align_coord[3]=86;
qrcode->align_coord[4]=112;
}
if(ver==33)
{
qrcode->align_coord[1]=30;
qrcode->align_coord[2]=58;
qrcode->align_coord[3]=86;
qrcode->align_coord[4]=114;
}
if(ver==34)
{
qrcode->align_coord[1]=34;
qrcode->align_coord[2]=62;
qrcode->align_coord[3]=90;
qrcode->align_coord[4]=118;
}
if(ver>=35&&ver<=40)
qrcode->align_coord[6]=150+4*(ver-35);
if(ver==35)
{
qrcode->align_coord[1]=30;
qrcode->align_coord[2]=54;
qrcode->align_coord[3]=78;
qrcode->align_coord[4]=102;
qrcode->align_coord[5]=126;
qrcode->align_coord[6]=150+4*(ver-35);
}
if(ver==36)
{
qrcode->align_coord[1]=24;
qrcode->align_coord[2]=56;
qrcode->align_coord[3]=82;
qrcode->align_coord[4]=108;
qrcode->align_coord[5]=128;
}
if(ver==37)
{
qrcode->align_coord[1]=28;
qrcode->align_coord[2]=54;
qrcode->align_coord[3]=80;
qrcode->align_coord[4]=106;
qrcode->align_coord[5]=132;
}
if(ver==38)
{
qrcode->align_coord[1]=32;
qrcode->align_coord[2]=58;
qrcode->align_coord[3]=84;
qrcode->align_coord[4]=110;
qrcode->align_coord[5]=136;
}
if(ver==39)
{
qrcode->align_coord[1]=26;
qrcode->align_coord[2]=54;
qrcode->align_coord[3]=82;
qrcode->align_coord[4]=110;
qrcode->align_coord[5]=138;
}
if(ver==40)
{
qrcode->align_coord[1]=30;
qrcode->align_coord[2]=58;
qrcode->align_coord[3]=86;
qrcode->align_coord[4]=114;
qrcode->align_coord[5]=142;
}
if(ver>MAXVERSION)
{printf("超出版本限制!目前仅支持前14个版本\n");return;}
}
void QRinit(Qrcodeinfo* qrcode,int ver) //由指定版本号生成该二维码的其他信息
{
qrcode->ver=ver;
if(ver>MAXVERSION)
{printf("版本超出限制!目前仅支持前14个版本\n");return;}
qrcode->length=17+4*ver;
qrcode->align_n=calalign_n(ver);
getalign_coord(qrcode,ver);
if(ver==1) qrcode->funcn=202;
else qrcode->funcn=180+25*qrcode->align_n+2*qrcode->length-10*sqrt(3+qrcode->align_n);
qrcode->formatn=ver<=6? 31:67;
qrcode->datan=qrcode->length*qrcode->length-qrcode->funcn-qrcode->formatn;
qrcode->coden=qrcode->datan/8;
qrcode->ecodata=econfig[ver-1];
qrcode->msgn=(qrcode->datan-qrcode->ecodata.ecoden*8)/8*8; //按照标准,信息位数(不含纠错)应为8的倍数
qrcode->msgcode=qrcode->msgn/8;
qrcode->remainbit=qrcode->datan%8;
}
unsigned int getmsgn(unsigned int ver)
{
unsigned int funcn,formatn,datan,msgn;
formatn=ver<=6? 31:67;
if(ver==1) funcn=202;
else funcn=180+25*calalign_n(ver)+2*(17+4*ver)-10*sqrt(3+calalign_n(ver));
datan=(17+4*ver)*(17+4*ver)-funcn-formatn;
msgn=(datan-econfig[ver-1].ecoden*8)/8*8; //按照标准,信息位数(不含纠错)应为8的倍数
return msgn;
}
unsigned int getdatan(unsigned int ver)
{
unsigned int funcn,formatn,datan;
formatn=ver<=6? 31:67;
if(ver==1) funcn=202;
else funcn=180+25*calalign_n(ver)+2*(17+4*ver)-10*sqrt(3+calalign_n(ver));
datan=(17+4*ver)*(17+4*ver)-funcn-formatn;
return datan;
}
//分析数据类型,返回值说明:0表数字;1表8位字节;-1表暂不支持
int str_analysis(char* text)
{
int num=1;
for(;*text!=0;text++)
{
if(!(OFNUMBER(text)))
num=0;
}
if(num==1) return 0;
else return 1;
}
int numcal(int n) //数字模式:由数字个数计算所需的二进制数据位数
{
int coden,leftn,finn;
coden=n/3;
leftn=n%3;
if(leftn==0) finn=coden*10;
if(leftn==1) finn=coden*10+4;
if(leftn==2) finn=coden*10+7;
if(n<=235) finn+=4+10; //<288
else if(n<=1425) finn+=4+12; //从版本10开始,字符计数指示符的位数是12而不是10
else finn+=4+14;
return finn;
}
int asciical(int n)//八位字节模式:由ascii码个数计算所需的二进制数据位数
{
int finn=8*n;
if(n<=98) finn+=4+8;
else finn+=4+16;
return finn;
}
int ver_determine(char* text,int mode) //确定版本
{
unsigned int ver,len=strlen(text);
unsigned int num,msgn;
if(mode==NUMBERMODE) num=numcal(len);
else if(mode==ASCIIMODE) num=asciical(len);
else {printf("不能识别的错误\n");num=0;return -1;}
for(ver=1;ver<=MAXVERSION;ver++)
{
msgn=getmsgn(ver);
if(msgn<num)
{
if(ver==MAXVERSION) return -1;
msgn=getmsgn(ver+1);
if(msgn>=num)
return (ver+1);
}
else if(ver==1) return 1;
}
return -2;
}
char* itoa(int,c