private static void SaveByteToBitArray(ref BitArray arr, byte data, int countBits = 8) { byte mask = (byte)(1 << (countBits - 1)); for (int i = 0; i < countBits; i++) { arr = QRCodesUtils.LeftShift(arr, 1); arr[0] = (data & mask) != 0 ? true : false; data <<= 1; } }
/// <summary> /// Creates a QR code in the binary encoding. /// </summary> /// <param name="data">The user data for encoding.</param> /// <param name="version">The QR code version.</param> /// <param name="levelCorrection">The level of error correction.</param> /// <returns>byte[]</returns> public static byte[] EncodeQRCodeData(string data, int version, QRCodeErrorCorrection levelCorrection) { BitArray arrData; UTF8Encoding utf8 = new UTF8Encoding(); var arrBytes = utf8.GetBytes(data); byte codeMethod = MethodCode(QRCodeEncodingMethod.Binary); int lengthStandard = QRCodesData.QRCodeMaxLengths[version - 1][(int)levelCorrection]; arrData = new BitArray(lengthStandard); int bitsSaved = 0; // Write the header if (version < 10) { SaveByteToBitArray(ref arrData, codeMethod, 4); SaveByteToBitArray(ref arrData, (byte)arrBytes.Length); bitsSaved += 12; } else { SaveByteToBitArray(ref arrData, codeMethod, 4); SaveByteToBitArray(ref arrData, (byte)((arrBytes.Length >> 8) & 0xFF)); SaveByteToBitArray(ref arrData, (byte)(arrBytes.Length & 0xFF)); bitsSaved += 20; } // No space for data error if ((arrBytes.Length << 3) + bitsSaved + (bitsSaved % 8) > lengthStandard) { throw new InvalidOperationException(); } // Write the data foreach (var byteData in arrBytes) { SaveByteToBitArray(ref arrData, byteData); } // Align to full bytes size bitsSaved += arrBytes.Length << 3; int bitsTail = bitsSaved % 8; arrData = QRCodesUtils.LeftShift(arrData, bitsTail); AlignToFullSize(ref arrData, bitsSaved + bitsTail, lengthStandard); int countBlocks = QRCodesData.QRCodeBlockCounts[version - 1][(int)levelCorrection]; var lengthBlocks = GetLengthOfBlocks(lengthStandard, countBlocks); // Split the data into blocks var dataBlocks = GetBlocks(lengthBlocks, arrData); var countCorrection = QRCodesData.QRCodeCorrectionCounts[version - 1][(int)levelCorrection]; byte[] kCorrection = QRCodesData.QRCodeCorrectionK[(byte)countCorrection]; // Add correction codes to the blocks and return results return(AddCorrectionCodeToBlocks(dataBlocks, countCorrection, kCorrection)); }