private static BitArray generateCheckWords(BitArray bitArray, int totalBits, int wordSize) { int i = 0; int messageSizeInWords = bitArray.getSize() / wordSize; ReedSolomonEncoder rs = new ReedSolomonEncoder(getGF(wordSize)); int totalWords = totalBits / wordSize; int[] messageWords = bitsToWords(bitArray, wordSize, totalWords); rs.encode(messageWords, totalWords - messageSizeInWords); int startPad = totalBits % wordSize; BitArray messageBits = new BitArray(); messageBits.appendBits(0, startPad); int length = messageWords.length; while (i < length) { messageBits.appendBits(messageWords[i], wordSize); i++; } return messageBits; }
static BitArray generateCheckWords(BitArray stuffedBits, int totalSymbolBits, int wordSize) { int messageSizeInWords = (stuffedBits.getSize() + wordSize - 1) / wordSize; for (int i = messageSizeInWords * wordSize - stuffedBits.getSize(); i > 0; i--) { stuffedBits.appendBit(true); } ReedSolomonEncoder rs = new ReedSolomonEncoder(getGF(wordSize)); int totalSizeInFullWords = totalSymbolBits / wordSize; int[] messageWords = bitsToWords(stuffedBits, wordSize, totalSizeInFullWords); rs.encode(messageWords, totalSizeInFullWords - messageSizeInWords); int startPad = totalSymbolBits % wordSize; BitArray messageBits = new BitArray(); messageBits.appendBits(0, startPad); for (int messageWord : messageWords) { messageBits.appendBits(messageWord, wordSize); } return messageBits; }
static byte[] a(byte abyte0[], int i) { int j = 0; int k = abyte0.length; int ai[] = new int[k + i]; for (int l = 0; l < k; l++) { ai[l] = 0xff & abyte0[l]; } (new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256)).encode(ai, i); byte abyte1[] = new byte[i]; for (; j < i; j++) { abyte1[j] = (byte)ai[k + j]; } return abyte1; }
private byte[] addECC(byte[] input) { if (input == null) { throw new IllegalArgumentException("The input to error correction code cannot be null"); } if (input.length > (maxBytes - errorCorrectionBytes)) { throw new IllegalArgumentException("The input to error correction code plus error correction bytes cannot be longer than 256"); } //convert byte[] to int[] into an array large enough to hold the ECC int[] ints = new int[input.length + errorCorrectionBytes]; for (int i = 0; i < input.length; i++) { ints[i] = input[i] & 0xFF; } ReedSolomonEncoder e = new ReedSolomonEncoder(gf); e.encode(ints, errorCorrectionBytes); //convert int[] to byte[] byte[] output = new byte[ints.length]; for (int i = 0; i < ints.length; i++) { output[i] = (byte) ints[i]; } return output; }
/** * Generate the Error correction codewords thanks to the Zxing external library. * * @todo auto convert int array to byte string * * @param dataBytes * @param numEcBytesInBlock * @return ecInt */ public int[] generateECBytes(byte[] dataBytes, int numEcBytesInBlock) { int numDataBytes = dataBytes.length; int[] toEncode = new int[numDataBytes + numEcBytesInBlock]; for (int i = 0; i < numDataBytes; i++) { toEncode[i] = dataBytes[i] & 0xFF; } new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256).encode(toEncode, numEcBytesInBlock); int[] ecInt = new int[numEcBytesInBlock]; for (int i = 0; i < numEcBytesInBlock; i++) { ecInt[i] = (int) ((byte) toEncode[numDataBytes + i] & 0xFF) ; } return ecInt; }
static byte[] generateECBytes(byte[] dataBytes, int numEcBytesInBlock) { int numDataBytes = dataBytes.length; int[] toEncode = new int[numDataBytes + numEcBytesInBlock]; for (int i = 0; i < numDataBytes; i++) { toEncode[i] = dataBytes[i] & 0xFF; } new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256).encode(toEncode, numEcBytesInBlock); byte[] ecBytes = new byte[numEcBytesInBlock]; for (int i = 0; i < numEcBytesInBlock; i++) { ecBytes[i] = (byte) toEncode[numDataBytes + i]; } return ecBytes; }
private static BitArray generateCheckWords(BitArray bitArray, int totalBits, int wordSize) { // bitArray is guaranteed to be a multiple of the wordSize, so no padding needed int messageSizeInWords = bitArray.getSize() / wordSize; ReedSolomonEncoder rs = new ReedSolomonEncoder(getGF(wordSize)); int totalWords = totalBits / wordSize; int[] messageWords = bitsToWords(bitArray, wordSize, totalWords); rs.encode(messageWords, totalWords - messageSizeInWords); int startPad = totalBits % wordSize; BitArray messageBits = new BitArray(); messageBits.appendBits(0, startPad); for (int messageWord : messageWords) { messageBits.appendBits(messageWord, wordSize); } return messageBits; }
static byte[] generateECBytes(byte[] dataBytes, int numEcBytesInBlock) { int i; int numDataBytes = dataBytes.length; int[] toEncode = new int[(numDataBytes + numEcBytesInBlock)]; for (i = 0; i < numDataBytes; i++) { toEncode[i] = dataBytes[i] & 255; } new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256).encode(toEncode, numEcBytesInBlock); byte[] ecBytes = new byte[numEcBytesInBlock]; for (i = 0; i < numEcBytesInBlock; i++) { ecBytes[i] = (byte) toEncode[numDataBytes + i]; } return ecBytes; }
public BitBlock(int numberOfDataBytes, int numberOfCheckBytes, ReedSolomonEncoder encoder, byte[] primaryDataBytes, int primaryDataIndex, byte[] primaryCheckBytes, int primaryCheckIndex) throws QArtException { this.numberOfDataBytes = numberOfDataBytes; this.numberOfCheckBytes = numberOfCheckBytes; this.encoder = encoder; this.blockBytes = new byte[numberOfDataBytes + numberOfCheckBytes]; this.primaryDataBytes = primaryDataBytes; this.primaryDataIndex = primaryDataIndex; this.primaryCheckBytes = primaryCheckBytes; this.primaryCheckIndex = primaryCheckIndex; System.arraycopy(primaryDataBytes, primaryDataIndex, blockBytes, 0, numberOfDataBytes); byte[] checkBytes = ReedSolomonUtil.generateECBytes(encoder, blockBytes, 0, numberOfDataBytes, numberOfCheckBytes); System.arraycopy(checkBytes, 0, blockBytes, numberOfDataBytes, numberOfCheckBytes); byte[] expectCheckBytes = new byte[numberOfCheckBytes]; System.arraycopy(primaryCheckBytes, primaryCheckIndex, expectCheckBytes, 0, numberOfCheckBytes); if(!Arrays.equals(expectCheckBytes, checkBytes)) { throw new QArtException("check data not match"); } this.maskMatrix = new byte[numberOfDataBytes*8][numberOfDataBytes + numberOfCheckBytes]; this.maskIndex = this.maskMatrix.length; for(int i = 0;i < numberOfDataBytes*8;i++) { for(int j = 0;j < numberOfDataBytes + numberOfCheckBytes;j++) { maskMatrix[i][j] = 0; } maskMatrix[i][i/8] = (byte) (1 << (7 - i%8)); checkBytes = ReedSolomonUtil.generateECBytes(encoder, maskMatrix[i], 0, numberOfDataBytes, numberOfCheckBytes); System.arraycopy(checkBytes, 0, maskMatrix[i], numberOfDataBytes, numberOfCheckBytes); } }
public static byte[] generateECBytes(ReedSolomonEncoder encoder, byte[] dataBytes, int position, int length, int numEcBytesInBlock) { int numDataBytes = length; int[] toEncode = new int[numDataBytes + numEcBytesInBlock]; for (int i = 0; i < numDataBytes; i++) { toEncode[i] = dataBytes[position + i] & 0xFF; } encoder.encode(toEncode, numEcBytesInBlock); byte[] ecBytes = new byte[numEcBytesInBlock]; for (int i = 0; i < numEcBytesInBlock; i++) { ecBytes[i] = (byte) toEncode[numDataBytes + i]; } return ecBytes; }
public void addCheckBytes(Version version, Level level) throws QArtException { int numberOfDataBytes = version.dataBytes(level); if (this.size < numberOfDataBytes*8) { pad(numberOfDataBytes*8 - this.size); } if (this.size != numberOfDataBytes*8) { throw new IllegalArgumentException("qr: too much data"); } Version.VersionInfo versionInfo = Version.VERSION_INFOS[version.getVersion()]; Version.VersionLevelInfo levelInfo = versionInfo.levelInfos[level.ordinal()]; int numberOfDataBytesPerBlock = numberOfDataBytes / levelInfo.numberOfBlocks; int numberOfExtraBytes = numberOfDataBytes % levelInfo.numberOfBlocks; ReedSolomonEncoder reedSolomonEncoder = new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256); int dataIndex = 0; for(int i = 0;i < levelInfo.numberOfBlocks;i++){ if(i == levelInfo.numberOfBlocks - numberOfExtraBytes) { numberOfDataBytesPerBlock++; } byte[] checkBytes = ReedSolomonUtil.generateECBytes(reedSolomonEncoder, this.bits, dataIndex, numberOfDataBytesPerBlock, levelInfo.numberOfCheckBytesPerBlock); dataIndex += numberOfDataBytesPerBlock; this.append(new Bits(checkBytes, levelInfo.numberOfCheckBytesPerBlock * 8)); } if(this.size/8 != versionInfo.bytes) { throw new QArtException("qr: internal error"); } }
/** Encode using Reed-Solomon error correction (with n bytes added to the end of bits). */ public static Bits bitsReedSolomonEncode(final Bits bits, final int n) { final int[] data = Arrays.copyOf(bits.getBytes(), (bits.size() + 7) / 8 + n); final ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256); enc.encode(data, n); final Bits result = new Bits(bits); for (int i = data.length - n; i < data.length; i++) { result.addValue(data[i], 8); } return result; }