⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decoder.c

📁 QR Code码的解码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
	Cstr_cleanup(&ttmp);
	// validate key
	unsigned char testkey = pl;
	for (i = 0; i < pl; i++)
		testkey += pass[i] - 48 + i;
	testkey %= 64;
	l=strlen(text->str);
	for (i = 0; i < l; i++)
		testkey += *(text->str+i) + i;
	testkey %= 64;
	if(testkey == key){
	    free(ciphertext);
		return 1;
	}
	else{
	    free(text->str);
	    text->str=ciphertext;
	    text->length=strlen(text->str);
	    text->num=text->length/text->size+1;
	    pass[0]='\0';
	}
    return 0;
}

int decode(char* iData, unsigned char iWidth, Cstr* text, char* pass)
{
    // iData 是一个bool ** 双指针,相当于二维数组
    // 查看Format及Version信息
    // 合成Data codewords及Error Correction codewords
    // 纠错

	unsigned char version = (iWidth-17)/4;
	char ecl = -1;
	char mask = -1;

  	// format information
	char infData[] = {*(iData+8*iWidth),*(iData+8*iWidth+1),*(iData+8*iWidth+2),
	                *(iData+8*iWidth+3),*(iData+8*iWidth+4),*(iData+8*iWidth+5),
	                *(iData+8*iWidth+7),*(iData+8*iWidth+8),*(iData+7*iWidth+8),
	                *(iData+5*iWidth+7),*(iData+4*iWidth+8),*(iData+3*iWidth+8),
	                *(iData+2*iWidth+7),*(iData+1*iWidth+8),*(iData+8)};
	unsigned char infMask[] = {1,0,1,0,1,0,0,0,0,0,1,0,0,1,0};
	int i,j,k;
  	for(i=0;i<15;i++)
		infData[i] ^= infMask[i];
	for(i=0;i<32;i++){
		unsigned char e = 0;
		for(j=0;j<15;j++){
			if(infData[j] != vfi[i][j]) e++;
			if(e>3) break;
		}
		if(e<=3){
			mask = vfi[i][2]*4+vfi[i][3]*2+vfi[i][4];
			ecl = vfi[i][0]*2+vfi[i][1];
			if(ecl % 2 ==0) ecl+=2;
			break;
		}
	}
	if (mask == -1 || ecl == -1)
		return -1;

	// fill iData with -1 except data and ec area
	// finder & seperator
	fillRect(iData, iWidth, 4, 4, 9);
	fillRect(iData, iWidth, 4, iWidth - 4, 8);
	fillRect(iData, iWidth, iWidth - 4, 4, 8);

	//alignment
	if (version > 1) {
		unsigned char aps = version / 7 + 2;
		for (i = 0; i < aps; i++) {
			for (j = 0; j < aps; j++) {
				if (i == 0 && j == 0)
					continue;
				if (i == 0 && j == aps - 1)
					continue;
				if (i == aps - 1 && j == 0)
					continue;
				fillRect(iData, iWidth, cm_of_ap[version][j], cm_of_ap[version][i], 5);
			}
		}		
	}

  	//timing
	for (i = 8; i < iWidth - 8; i ++) {
		*(iData+6*iWidth+i) = -1;
		*(iData+i*iWidth+6) = -1;
	}
	//format
	for (i = 0; i < 8; i++) {
		*(iData+8*iWidth+(iWidth-1-i)) = -1;
		*(iData+(iWidth-1-i)*iWidth+8) = -1;
	}
	//version
	if (version > 6) {
		for (i = 0; i < 3; i++) {
			for (j = 0; j < 6; j++) {
				*(iData+j*iWidth+(iWidth-9-i)) = -1;
				*(iData+(iWidth-9-i)*iWidth+j) = -1;
			}
		}
	}
	
	//matrix to codeword
	unsigned char* ecb = num_of_ecb[(version - 1) * 4 + ecl - 1];
	unsigned char* dae = dae_per_block[(version - 1) * 4 + ecl - 1];
	int tCodeword = 0;
	int tBlocks = 0;
	int ecblen = 0;
	for (i = 0; i < 2; i++) 
		if(ecb[i] != 0 ){
			tCodeword += dae[i * 2] * ecb[i];
			tBlocks += ecb[i];
			ecblen++;
		}

	int blockWidth =  dae[ecblen * 2 - 2];
	//int dCodewordWidth = dae[ecblen * 2 - 1];
	//int eCodewordWidth = dae[ecblen * 2 - 2] - dCodewordWidth;

	unsigned char* blocks = (unsigned char*)malloc(SCHAR*tBlocks*blockWidth);
	memset(blocks, '\0', tBlocks*blockWidth);
	int cx = iWidth, cy = iWidth-1, direction = 1;
	for(j = 0; j < blockWidth; j++) {
		for(i = 0;	i < tBlocks; i++) {	
			if(ecblen == 2 && i < ecb[0] && j == dae[1]) {
				continue;
			}
			else {
				unsigned char pow = 7;
				*(blocks+i*blockWidth+j) = 0;
				int cwi;
				for (cwi = 0; cwi < 8; cwi++) {
					do {
						if (cx > 6) {
							if (cx % 2 == 1) {
								if (cy + direction == iWidth) {
									direction = -1;
									cx--;
									if (cx == 6)
										cx = 5;
								} else if (cy + direction == -1) {
									direction = 1;
									cx--;
									if (cx == 6)
										cx = 5;
								} else {
									cy += direction;
									cx++;
								}
							} else {
								cx--;
							}
						} else {
							if (cx % 2 == 0) {
								if (cy + direction == iWidth) {
									direction = -1;
									cx--;
								} else if (cy + direction == -1) {
									direction = 1;
									cx--;
								} else {
									cy += direction;
									cx++;
								}
							} else {
								cx--;
							}
						}
					} while (*(iData+cy*iWidth+cx) < 0);					
					*(iData+cy*iWidth+cx) ^= maskPattern(cy,cx,mask);
					*(blocks+i*blockWidth+j) += *(iData+cy*iWidth+cx) << pow--;
				}
			}
		}
	}
	
	//移位ec
	if(ecblen == 2){
		for(i = 0;	i < ecb[0]; i++) {	
			for(j = dae[1]; j < blockWidth - 1; j++) {
				*(blocks+i*blockWidth+j) = *(blocks+i*blockWidth+j+1);
			}
		}
	}

	// 解码结果
	char ifNext = 1;
	// CorrectErrs(unsigned char * aSym, int aDSize, int aECSize, int aP)
	for (i = 0; i < tBlocks; i ++)
	{
		int e = 0;
		if ((e = CorrectErrs((blocks+i*blockWidth), i<ecb[0]?dae[1]:dae[3], dae[0]-dae[1], version<4?P[(version - 1) * 4 + ecl - 1]:0)) == -1)
		{
			ifNext = 0;
            printf("UnCorrectable.\n");
		}
		else if(e!=0){
            printf("Errors %d in line %d.\n",e,i);
		}
	}

	//decode
	if (ifNext) {
		int bit = 0;
		i=j=0;
		while(1){
			// mode
			int mode = 0, len= 0 ;
			int n = 4;
			for(k = n - 1; k >= 0; k--){
				mode += getbit(*(blocks+i*blockWidth+j), bit)<<k;
				if(++bit==8){
					bit=0;
					j++;
					if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
						j=0;
						i++;
					}
				}
			}
			// terminator
			if(mode == 0) break;
			// data text
			switch(mode){
				case 1:
					n = version<10?10:(version<27?12:14);
					for(k = n - 1; k >= 0; k--){
						len += getbit(*(blocks+i*blockWidth+j), bit)<<k;
						if(++bit==8){
							bit=0;
							j++;
							if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
								j=0;
								i++;
							}
						}
					}
					for (k = 0; k < len / 3; k++) {
						int v = 0;
						int kk;
						for(kk = 9; kk >= 0; kk--){
							v += getbit(*(blocks+i*blockWidth+j), bit)<<kk;
							if(++bit==8){
								bit=0;
								j++;
								if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
									j=0;
									i++;
								}
							}
						}
						if(v < 100) Cstr_appendc(text ,'0');
						else if(v < 10) Cstr_appends(text ,"00");;
						char c[4];
						itoa(v, c, 10);
						Cstr_appends(text ,c);
					}
					if (len % 3 != 0) {
						int v = 0;
						int kk;
						for(kk = (len % 3) * 3; kk >= 0; kk--){
							v += getbit(*(blocks+i*blockWidth+j), bit)<<kk;
							if(++bit==8){
								bit=0;
								j++;
								if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
									j=0;
									i++;
								}
							}
						}
						if(v < 10 && len % 3 == 2) Cstr_appendc(text, '0');
						char c[4];
						itoa(v, c, 10);
						Cstr_appends(text ,c);
					}
					break;
				case 2:
					n = version<10?9:(version<27?11:13);
					for(k = n - 1; k >= 0; k--){
						len += getbit(*(blocks+i*blockWidth+j), bit)<<k;
						if(++bit==8){
							bit=0;
							j++;
							if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
								j=0;
								i++;
							}
						}
					}
					for (k = 0; k < len / 2; k++) {
						int v = 0;
						int kk;
						for(kk = 10; kk >= 0; kk--){
							v += getbit(*(blocks+i*blockWidth+j), bit)<<kk;
							if(++bit==8){
								bit=0;
								j++;
								if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
									j=0;
									i++;
								}
							}
						}
						Cstr_appendc(text, tAlpha[v / 45]);
						Cstr_appendc(text, tAlpha[v % 45]);
					}
					if (len % 2 != 0) {
						int v = 0;
						int kk;
						for(kk = 5; kk >= 0; kk--){
							v += getbit(*(blocks+i*blockWidth+j), bit)<<kk;
							if(++bit==8){
								bit=0;
								j++;
								if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
									j=0;
									i++;
								}
							}
						}
						Cstr_appendc(text, tAlpha[v]);
					}
					break;
				case 4:
					n = version<10?8:(version<27?16:16);
					for(k = n - 1; k >= 0; k--){
						len += getbit(*(blocks+i*blockWidth+j), bit)<<k;
						if(++bit==8){
							bit=0;
							j++;
							if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
								j=0;
								i++;
							}
						}
					}
					for (k = 0; k < len; k++) {
						char v = 0;
						int kk;
						for(kk = 7; kk >= 0; kk--){
							v += getbit(*(blocks+i*blockWidth+j), bit)<<kk;
							if(++bit==8){
								bit=0;
								j++;
								if((ecblen == 2 && i < ecb[0] && j == dae[1]) || (j == dae[ecblen * 2 -1])) {
									j=0;
									i++;
								}
							}
						}
						Cstr_appendc(text, v);
					}
					break;
				}
          }
	}
	free(blocks);
	//return 1;
	return isEncrypted(text, pass);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -