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

📄 qrcodedatablockreader.java

📁 一款用Java实现QR解码的源代码。
💻 JAVA
字号:
/*
 * 嶌惉擔丗 2004/10/04
 *
 * TODO 偙偺惗惉偝傟偨僼傽僀儖偺僥儞僾儗乕僩傪曄峏偡傞偵偼師傪嶲徠丅
 * 僂傿儞僪僂 亜 愝掕 亜 Java 亜 僐乕僪丒僗僞僀儖 亜 僐乕僪丒僥儞僾儗乕僩
 */
package jp.sourceforge.qrcode.codec.reader;

import jp.sourceforge.qrcode.codec.util.DebugCanvas;
/**
 * @author Owner
 *
 * TODO 偙偺惗惉偝傟偨宆僐儊儞僩偺僥儞僾儗乕僩傪曄峏偡傞偵偼師傪嶲徠丅
 * 僂傿儞僪僂 亜 愝掕 亜 Java 亜 僐乕僪丒僗僞僀儖 亜 僐乕僪丒僥儞僾儗乕僩
 */
public class QRCodeDataBlockReader {
	int[] blocks;
	int version;
	int mode = -1;
	int blockPointer;
	int bitPointer;
	int dataLength;
	DebugCanvas canvas;
	final int MODE_NUMBER = 1;
	final int MODE_ROMAN_AND_NUMBER = 2;
	final int MODE_8BIT_BYTE = 4;
	final int MODE_KANJI = 8;

	public QRCodeDataBlockReader(int[] blocks, int version) {
		blockPointer = 0;
		bitPointer = 7;
		dataLength = 0;
		this.blocks = blocks;
		this.version = version;
		canvas = DebugCanvas.getCanvas();
	}
	
	int getNextBits(int numBits) throws ArrayIndexOutOfBoundsException {
//		System.out.println("numBits:" + String.valueOf(numBits));
//		System.out.println("blockPointer:" + String.valueOf(blockPointer));
//		System.out.println("bitPointer:" + String.valueOf(bitPointer));
		if (numBits < bitPointer + 1) { // 1偮偺僽儘僢僋偱廂傑傞
			int mask = 0;
			for (int i = 0; i < numBits; i++) {
				mask += 1 << i;
			}
			mask <<= (bitPointer - numBits + 1);
			
			int bits = (blocks[blockPointer] & mask) >> (bitPointer - numBits + 1);
			bitPointer -= numBits;
			return bits;
		}
		else if (numBits < bitPointer + 1 + 8) { //2偮偺僽儘僢僋偵傑偨偑傞
			int mask1 = 0;
			int mask2 = 0;
			for (int i = 0; i < bitPointer + 1; i++) {
				mask1 += 1 << i;
			}
			int bits = (blocks[blockPointer] & mask1) << (numBits - (bitPointer + 1));
			blockPointer++;

			bits += (blocks[blockPointer]) >> (8 - (numBits - (bitPointer + 1)));

	
			bitPointer = bitPointer - numBits % 8;
			if (bitPointer < 0) {
				bitPointer = 8 + bitPointer;
			}
			return bits;	
		}
		else if (numBits < bitPointer + 1 + 16) { //3偮偺僽儘僢僋偵傑偨偑傞
			int mask1 = 0; //戞1僽儘僢僋偺儅僗僋
			int mask3 = 0; //戞3僽儘僢僋偺儅僗僋
			//bitPointer + 1 : 戞1僽儘僢僋偺價僢僩悢
			//8 : 戞2僽儘僢僋偺價僢僩悢(忢偵8)
			//numBits - (bitPointer + 1 + 8) : 戞3僽儘僢僋偺價僢僩悢
			for (int i = 0; i < bitPointer + 1; i++) {
				mask1 += 1 << i;
			}
			int bitsFirstBlock = (blocks[blockPointer] & mask1) << (numBits - (bitPointer + 1));
			blockPointer++;

			int bitsSecondBlock = blocks[blockPointer] << (numBits - (bitPointer + 1 + 8));
			blockPointer++;
			
			for (int i = 0; i < numBits - (bitPointer + 1 + 8); i++) {
				mask3 += 1 << i;
			}
			mask3 <<= 8 - (numBits - (bitPointer + 1 + 8));
			int bitsThirdBlock = (blocks[blockPointer] & mask3) >> (8 - (numBits - (bitPointer + 1 + 8)));
			
			int bits = bitsFirstBlock + bitsSecondBlock + bitsThirdBlock;
			bitPointer = bitPointer - (numBits - 8) % 8;
			if (bitPointer < 0) {
				bitPointer = 8 + bitPointer;
			}
			return bits;
		}
		else {
			System.out.println("ERROR!");
			return 0;
		}
	}	
	
	int getNextMode() throws ArrayIndexOutOfBoundsException {
		return getNextBits(4);
	}
	
	int guessMode(int mode) {
		//0001 0010 0011 0100
		//0101 0110 0111 1000
		
		if (mode == 3)
			return MODE_ROMAN_AND_NUMBER;
//		else if (mode == 5 || mode == 6)  
//			return MODE_8BIT_BYTE;
		else // mode > 8
			return MODE_KANJI;
	}

	int getDataLength(int mode) throws ArrayIndexOutOfBoundsException {
		switch (mode) {
		case MODE_NUMBER:
			if (version <= 9)
				return getNextBits(10);
			else if (version >= 10 && version <= 26)
				return getNextBits(12);
		case MODE_ROMAN_AND_NUMBER:
			if (version <= 9)
				return getNextBits(9);
			else if (version >= 10 && version <= 26)
				return getNextBits(11);
		case MODE_8BIT_BYTE:
			if (version <= 9)
				return getNextBits(8);
			else if (version >= 10 && version <= 26)
				return getNextBits(16);
		case MODE_KANJI:
			if (version <= 9)
				return getNextBits(8);
			else if (version >= 10 && version <= 26)
				return getNextBits(10);
		default:
				return 0;
		}
	}	
	
	public String getDataString() throws ArrayIndexOutOfBoundsException {
		canvas.println("Reading data blocks.");
		String dataString = "";
		do {
			mode = getNextMode();
			//System.out.println("mode: " + mode);
			if (mode == 0)
				break;
			//if (mode != 1 && mode != 2 && mode != 4 && mode != 8)
			//	break;
			//}
			if (mode != MODE_NUMBER && mode != MODE_ROMAN_AND_NUMBER &&
					mode != MODE_8BIT_BYTE && mode != MODE_KANJI) {
				mode = guessMode(mode);
				//System.out.println("guessed mode: " + mode);

			}
				
			dataLength = getDataLength(mode);
			//System.out.println("length: " + dataLength);
			switch (mode) {
			case MODE_NUMBER: //悢帤儌乕僪
				//canvas.println("Mode: Figure");
				dataString += getFigureString(dataLength);
				break;
			case MODE_ROMAN_AND_NUMBER: //塸悢帤儌乕僪
				//canvas.println("Mode: Roman&Figure");
				dataString += getRomanAndFigureString(dataLength);
				break;
			case MODE_8BIT_BYTE: //8價僢僩僶僀僩儌乕僪
				//canvas.println("Mode: 8bit Byte");
				dataString += get8bitByteString(dataLength);
				break;
			case MODE_KANJI: //娍帤儌乕僪
				//canvas.println("Mode: Kanji");
				dataString += getKanjiString(dataLength);
				break;
			}
			//canvas.println("DataLength: " + dataLength);
			//System.out.println(dataString);
		} while (true);
		System.out.println("");
		return dataString;
	}
	
	
	String getFigureString(int dataLength) throws ArrayIndexOutOfBoundsException {
		int length = dataLength;
		int intData = 0;
		String strData = "";
		do {
			if (length >= 3) {
				intData = getNextBits(10);
				if (intData < 100) strData += "0";
				if (intData < 10) strData += "0";
				length -= 3;
			}
			else if (length == 2) {
				intData = getNextBits(7);
				if (intData < 10) strData += "0";
				length -= 2;
			}
			else if (length == 1) {
				intData = getNextBits(4);
				length -= 1;
			}				
			strData += Integer.toString(intData);
		} while (length > 0);
		
		return strData;
	}
	
	String getRomanAndFigureString(int dataLength) throws ArrayIndexOutOfBoundsException  {
		int length = dataLength;
		int intData = 0;
		String strData = "";
		final char[] tableRomanAndFigure = {
			 '0', '1', '2', '3', '4', '5',
	 		 '6', '7', '8', '9', 'A', 'B',
			 'C', 'D', 'E', 'F', 'G', 'H',
			 'I', 'J', 'K', 'L', 'M', 'N',
			 'O', 'P', 'Q', 'R', 'S', 'T',
			 'U', 'V', 'W', 'X', 'Y', 'Z',
			 ' ', '$', '%', '*', '+', '-',
			 '.', '/', ':'
			 };
		do {
			if (length > 1) {
				intData = getNextBits(11);
				int firstLetter = intData / 45;
				int secondLetter = intData % 45;
				strData += String.valueOf(tableRomanAndFigure[firstLetter]);
				strData += String.valueOf(tableRomanAndFigure[secondLetter]);
				length -= 2;
			}
			else if (length == 1) {
				intData = getNextBits(6);
				strData += String.valueOf(tableRomanAndFigure[intData]);
				length -= 1;
			}
		} while (length > 0);
		
		return strData;
	}
	
	String get8bitByteString(int dataLength) throws ArrayIndexOutOfBoundsException  {
		int length = dataLength;
		int intData = 0;
		String strData = "";
		final char[] table8bitByte = {
			' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\n', ' ', ' ', ' ', ' ', ' ', 
			' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 
			' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',  
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', 
			'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 
			'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', 
			'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 
			'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', ' ', 
			' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 
			' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 
			' ', '

⌨️ 快捷键说明

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