📄 qrcode.java
字号:
try { String filename = QRCODE_DATA_PATH+"/qrvfr"+Integer.toString(qrcodeVersion)+".dat"; InputStream fis =Qrcode.class.getResourceAsStream(filename); BufferedInputStream bis = new BufferedInputStream(fis); bis.read(frameData); bis.close(); fis.close(); } catch(Exception e) { e.printStackTrace(); }/* --- set terminator */ if (totalDataBits<=maxDataBits-4){ dataValue[dataCounter]=0; dataBits[dataCounter]=4; } else { if (totalDataBits<maxDataBits){ dataValue[dataCounter]=0; dataBits[dataCounter]=(byte)(maxDataBits-totalDataBits); } else { if (totalDataBits>maxDataBits){ System.out.println("overflow"); } } } byte[] dataCodewords=divideDataBy8Bits(dataValue,dataBits,maxDataCodewords); byte[] codewords = calculateRSECC(dataCodewords,rsEccCodewords[0],rsBlockOrder,maxDataCodewords,maxCodewords);/* ---- flash matrix */byte[][] matrixContent = new byte[modules1Side][modules1Side];for (int i=0;i<modules1Side;i++){ for (int j=0; j<modules1Side;j++){ matrixContent[j][i]=0; }}/* --- attach data */for (int i=0;i<maxCodewords;i++){ byte codeword_i=codewords[i]; for (int j=7;j>=0;j--){ int codewordBitsNumber=(i*8) + j; matrixContent[ matrixX[codewordBitsNumber] & 0xFF][ matrixY[codewordBitsNumber] & 0xFF]=(byte)((255*(codeword_i & 1)) ^ maskArray[codewordBitsNumber] ); codeword_i=(byte)((codeword_i & 0xFF)>>> 1); }}for (int matrixRemain=matrixRemainBit[qrcodeVersion];matrixRemain>0;matrixRemain--){ int remainBitTemp = matrixRemain + ( maxCodewords *8)-1; matrixContent[ matrixX[remainBitTemp] & 0xFF ][ matrixY[remainBitTemp] & 0xFF ] = (byte)( 255 ^ maskArray[remainBitTemp] );}/* --- mask select --- */byte maskNumber=selectMask(matrixContent,matrixRemainBit[qrcodeVersion]+maxCodewords*8);byte maskContent=(byte)(1 << maskNumber);/* --- format information --- */byte formatInformationValue=(byte)(ec << 3 | maskNumber);String[] formatInformationArray={"101010000010010","101000100100101","101111001111100","101101101001011","100010111111001","100000011001110","100111110010111","100101010100000","111011111000100","111001011110011","111110110101010","111100010011101","110011000101111","110001100011000","110110001000001","110100101110110","001011010001001","001001110111110","001110011100111","001100111010000","000011101100010","000001001010101","000110100001100","000100000111011","011010101011111","011000001101000","011111100110001","011101000000110","010010010110100","010000110000011","010111011011010","010101111101101"};for (int i=0;i<15;i++){ byte content=Byte.parseByte(formatInformationArray[formatInformationValue].substring(i,i+1)); matrixContent[formatInformationX1[i] & 0xFF][formatInformationY1[i] & 0xFF]=(byte)(content * 255); matrixContent[formatInformationX2[i] & 0xFF][formatInformationY2[i] & 0xFF]=(byte)(content * 255);} boolean[][] out = new boolean[modules1Side][modules1Side];int c=0;for (int i=0;i<modules1Side;i++){ for (int j=0;j<modules1Side;j++){ if ((matrixContent[j][i] & maskContent)!=0 || frameData[c]==(char)49) { out[j][i]=true; } else { out[j][i]=false; } c++; } c++;}return out;}private static byte[] divideDataBy8Bits(int[] data ,byte[] bits,int maxDataCodewords){ /* divide Data By 8bit and add padding char */ int l1=bits.length; int l2; int codewordsCounter=0; int remainingBits=8; int max=0; int buffer; int bufferBits; boolean flag; if (l1!=data.length){ } for (int i=0; i<l1; i++){ max+=bits[i]; } l2 =(max-1)/8+1; byte[] codewords=new byte[maxDataCodewords]; for (int i=0; i<l2; i++){ codewords[i]=0; } for (int i=0; i<l1; i++){ buffer=data[i]; bufferBits=bits[i]; flag=true; if (bufferBits==0) { break; } while (flag) { if (remainingBits>bufferBits){ codewords[codewordsCounter]=(byte)((codewords[codewordsCounter]<<bufferBits) | buffer); remainingBits-=bufferBits; flag=false; } else { bufferBits-=remainingBits; codewords[codewordsCounter]=(byte)((codewords[codewordsCounter] << remainingBits) | (buffer >> bufferBits)); if (bufferBits==0) { flag=false; } else { buffer= (buffer & ((1 << bufferBits)-1) ); flag=true; } codewordsCounter++; remainingBits=8; } } } if (remainingBits!=8) { codewords[codewordsCounter]=(byte)(codewords[codewordsCounter] << remainingBits); } else { codewordsCounter--; } if (codewordsCounter<maxDataCodewords-1){ flag=true; while (codewordsCounter<maxDataCodewords-1){ codewordsCounter++; if (flag) { codewords[codewordsCounter]=-20; } else { codewords[codewordsCounter]=17; } flag=!(flag); } } return codewords; } private static byte[] calculateRSECC(byte[] codewords, byte rsEccCodewords,byte[] rsBlockOrder,int maxDataCodewords,int maxCodewords){ byte[][] rsCalTableArray = new byte[256][rsEccCodewords]; try { String filename = QRCODE_DATA_PATH+"/rsc"+Byte.toString(rsEccCodewords)+".dat"; InputStream fis =Qrcode.class.getResourceAsStream(filename); BufferedInputStream bis = new BufferedInputStream(fis); for (int i=0;i<256;i++){ bis.read(rsCalTableArray[i]); } bis.close(); fis.close(); } catch(Exception e) { e.printStackTrace(); } /* ---- RS-ECC prepare */ int i=0; int j=0; int rsBlockNumber=0; byte[][] rsTemp = new byte[rsBlockOrder.length][]; byte res[] =new byte[maxCodewords]; System.arraycopy(codewords,0,res,0,codewords.length); i=0; while(i<rsBlockOrder.length){ rsTemp[i]=new byte[(rsBlockOrder[i] & 0xFF)-rsEccCodewords]; i++; } i=0; while(i<maxDataCodewords){ rsTemp[rsBlockNumber][j]=codewords[i]; j++; if (j>=(rsBlockOrder[rsBlockNumber]& 0xFF)-rsEccCodewords){ j=0; rsBlockNumber++; } i++; } /* --- RS-ECC main --- */ rsBlockNumber=0; while (rsBlockNumber<rsBlockOrder.length){ byte[] rsTempData; rsTempData=(byte[])rsTemp[rsBlockNumber].clone(); int rsCodewords=(rsBlockOrder[rsBlockNumber] & 0xFF); int rsDataCodewords=rsCodewords-rsEccCodewords; j=rsDataCodewords; while(j>0){ byte first=rsTempData[0]; if (first!=0){ byte[] leftChr=new byte[rsTempData.length-1]; System.arraycopy(rsTempData,1, leftChr,0,rsTempData.length-1); byte[] cal=rsCalTableArray[(first & 0xFF)]; rsTempData =calculateByteArrayBits(leftChr ,cal,"xor"); } else { if (rsEccCodewords<rsTempData.length){ byte[] rsTempNew =new byte[rsTempData.length-1]; System.arraycopy(rsTempData,1,rsTempNew,0,rsTempData.length-1); rsTempData =(byte[])rsTempNew.clone(); } else { byte[] rsTempNew =new byte[rsEccCodewords]; System.arraycopy(rsTempData,1,rsTempNew,0,rsTempData.length-1); rsTempNew[rsEccCodewords-1]=0; rsTempData =(byte[])rsTempNew.clone(); } } j--; } System.arraycopy(rsTempData,0,res,codewords.length+rsBlockNumber*rsEccCodewords,rsEccCodewords); rsBlockNumber++; } return res;}private static byte[] calculateByteArrayBits(byte[] xa,byte[] xb,String ind){ int ll; int ls; byte[] res; byte[] xl; byte[] xs; if (xa.length>xb.length){ xl = (byte[])xa.clone(); xs = (byte[])xb.clone(); } else { xl = (byte[])xb.clone(); xs = (byte[])xa.clone(); } ll = xl.length; ls = xs.length; res = new byte[ll]; for (int i=0; i<ll; i++){ if (i<ls){ if (ind=="xor"){ res[i]=(byte)(xl[i] ^ xs[i]); } else { res[i]=(byte)(xl[i] | xs[i]); } } else { res[i]=xl[i]; } } return res;}private static byte selectMask(byte[][] matrixContent,int maxCodewordsBitWithRemain){ int l=matrixContent.length; int[] d1={0,0,0,0,0,0,0,0}; int[] d2={0,0,0,0,0,0,0,0}; int[] d3={0,0,0,0,0,0,0,0}; int[] d4={0,0,0,0,0,0,0,0}; int d2And=0; int d2Or=0; int[] d4Counter={0,0,0,0,0,0,0,0}; for(int y=0;y<l;y++){ int[] xData={0,0,0,0,0,0,0,0}; int[] yData={0,0,0,0,0,0,0,0}; boolean[] xD1Flag={false,false,false,false,false,false,false,false}; boolean[] yD1Flag={false,false,false,false,false,false,false,false}; for (int x=0;x<l;x++){ if (x>0 && y>0){ d2And=matrixContent[x][y] & matrixContent[x-1][y] & matrixContent[x][y-1] & matrixContent[x-1][y-1]& 0xFF; d2Or=(matrixContent[x][y] & 0xFF) | (matrixContent[x-1][y] & 0xFF) | (matrixContent[x][y-1] & 0xFF) | (matrixContent[x-1][y-1] & 0xFF); } for(int maskNumber=0;maskNumber<8;maskNumber++){ xData[maskNumber]=((xData[maskNumber] & 63) << 1) | (((matrixContent[x][y] & 0xFF) >>> maskNumber) &1); yData[maskNumber]=((yData[maskNumber] & 63) << 1) | (((matrixContent[y][x] & 0xFF) >>> maskNumber) &1); if ((matrixContent[x][y] & (1 << maskNumber))!=0){ d4Counter[maskNumber]++; } if (xData[maskNumber]==93) { d3[maskNumber]+=40; } if (yData[maskNumber]==93) { d3[maskNumber]+=40; } if (x>0 && y>0){ if (((d2And & 1)!=0) || ((d2Or & 1)==0)) { d2[maskNumber]+=3; } d2And = d2And >> 1; d2Or = d2Or >>1; } if (((xData[maskNumber] & 0x1F)==0) || ((xData[maskNumber] &0x1F)==0x1F)){ if (x>3){ if (xD1Flag[maskNumber]){ d1[maskNumber]++; } else { d1[maskNumber]+=3; xD1Flag[maskNumber]=true; } } } else { xD1Flag[maskNumber]=false; } if (((yData[maskNumber] & 0x1F)==0) || ((yData[maskNumber] &0x1F)==0x1F)){ if (x>3){ if (yD1Flag[maskNumber]){ d1[maskNumber]++; } else { d1[maskNumber]+=3; yD1Flag[maskNumber]=true; } } } else { yD1Flag[maskNumber]=false; } } } } int minValue=0; byte res=0; int[] d4Value={90,80,70,60,50,40,30,20,10,0,0,10,20,30,40,50,60,70,80,90,90}; for (int maskNumber=0;maskNumber<8;maskNumber++){ d4[maskNumber]=d4Value[(int)((20*d4Counter[maskNumber])/maxCodewordsBitWithRemain)]; int demerit=d1[maskNumber]+d2[maskNumber]+d3[maskNumber]+d4[maskNumber]; if (demerit<minValue || maskNumber==0){ res=(byte)maskNumber; minValue=demerit; } } return res;}/*--- class end ---*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -