private void Run() { byte[] originalMessage = Encoding.UTF8.GetBytes("Nervously I loaded the twin ducks aboard the revolving platform."); var ecc = ReedSolomonAlgorithm.Encode(originalMessage, 32); Console.WriteLine($"Original message: {Encoding.UTF8.GetString(originalMessage)}"); Console.WriteLine($"Original ecc: {ByteArrayToString(ecc)}"); Console.WriteLine(); ByteError(0x35, 3, originalMessage); ByteError(0x51, 8, ecc); ByteErasure(17, originalMessage); ByteErasure(21, originalMessage); ByteErasure(16, ecc); ByteErasure(18, ecc); Console.WriteLine(); Console.WriteLine($"Damaged message: {Encoding.UTF8.GetString(originalMessage)}"); Console.WriteLine($"Damaged ecc: {ByteArrayToString(ecc)}"); Console.WriteLine(); //var newEcc = new byte[32]; //Array.Copy(ecc, newEcc, 32); byte[] decodedMessage = ReedSolomonAlgorithm.Decode(originalMessage, ecc); Console.WriteLine($"Decoded message: {Encoding.UTF8.GetString(decodedMessage)}"); }
/// <summary> /// Create the QRCode and the image corresponding /// </summary> /// <param name="message">message to encode in the QRCode</param> private QRCode(string message) { offsetSize = 54; imageType = "BM"; this.message = message.ToUpper(); encoding = "0010"; //Alphanumeric length = Int_To_Bits(message.Length, 9); messageBits = Encode_Message(); int eccCount = 0; if (type == 1) { eccCount = 7; } else { eccCount = 10; } byte[] error = ReedSolomonAlgorithm.Encode(BitsToByte(encoding + length + messageBits), eccCount, ErrorCorrectionCodeType.QRCode); this.error = ByteToBit(error); Console.WriteLine(encoding.Length + length.Length + messageBits.Length + this.error.Length); Console.WriteLine(encoding + length + messageBits + this.error); DrawCanvas(); WriteData(); DrawErrorCorrection(); int size = 6; image = new Pixel[size * (code.GetLength(0) + 2), size *(code.GetLength(1) + 2)]; for (int i = 0; i < image.GetLength(0); i++) { for (int j = 0; j < image.GetLength(1); j++) { if (i < size || j < size || i >= code.GetLength(0) * size + size || j >= code.GetLength(1) * size + size) { image[i, j] = Pixel.White; } else if (code[i / size - 1, j / size - 1] == 0) { image[i, j] = Pixel.White; } else { image[i, j] = Pixel.Black; } } } }
/// <summary> /// Encode the error into a string of bits /// </summary> /// <returns>the string of bits corresponding to the error</returns> public string EncodeError() { string result = ""; int eccCount = 0; if (type == 1) { eccCount = 7; } else if (type == 2) { eccCount = 10; } byte[] code = ReedSolomonAlgorithm.Encode(Encoding.UTF8.GetBytes(message), eccCount); result += ByteToBit(code); return(result); }
/// <summary> /// Decode a QRCode /// </summary> /// <param name="img">image containing the QRCode</param> private QRCode(MyImage img) { // Copy image on this object image = new Pixel[img.image.GetLength(0), img.image.GetLength(1)]; for (int i = 0; i < image.GetLength(0); i++) { for (int j = 0; j < image.GetLength(1); j++) { image[i, j] = new Pixel(img.image[i, j]); } } /* https://www.researchgate.net/publication/221337868_Fast_QR_Code_Detection_in_Arbitrarily_Acquired_Images */ //Assume image is flat on the surface //Find the size of a finder and the size of a code to determine the version //and the size of a bit to be accurate while reading // plus save the start index of QRCode; // Different size horizontal and vertical (if image is warped int sizeOfFinderHorizontal = 0; int sizeOfCodeHorizontal = 0; int sizeOfFinderVertical = 0; int sizeOfCodeVertical = 0; bool b = true; int line = 0; int column = 0; int startLine = 0; int startColumn = 0; //Searching while (b) { column = 0; while (column < image.GetLength(1) && !image[line, column].isCloseToBlack) { column++; } startColumn = column; startLine = line; // For horizontal size while (column < image.GetLength(1) && image[startLine, column].isCloseToBlack) { b = false; sizeOfFinderHorizontal++; column++; } // For Vertical size while (!b && line < image.GetLength(0) && image[line, startColumn].isCloseToBlack) { sizeOfFinderVertical++; line++; } if (!b) { // Horizontal size for (int j = image.GetLength(1) - 1; j >= 0 && sizeOfCodeHorizontal == 0; j--) { if (image[startLine, j].isCloseToBlack) { sizeOfCodeHorizontal = j - startColumn; } } // Vertical Size for (int j = image.GetLength(0) - 1; j >= 0 && sizeOfCodeVertical == 0; j--) { if (image[j, startColumn].isCloseToBlack) { sizeOfCodeVertical = j - startLine; } } } line++; } //Compute the size of a bit (finder is 7 pixels wide) int bitSizeHorizontal = sizeOfFinderHorizontal / 7; int bitSizeVertical = sizeOfFinderVertical / 7; int approxSize = sizeOfCodeHorizontal / bitSizeHorizontal; //Determine the version of QR based on the size if (approxSize < 23) { type = 1; } else { type = 2; } //Now read the QRCode but first Draw the Canvas DrawCanvas(); //Read DAta string messageBits = ReadData(bitSizeHorizontal, bitSizeVertical, startLine, startColumn); // Get rid of the last seven bits if type 2 if (type == 2) { messageBits = messageBits.Substring(0, 352); } Console.WriteLine(messageBits); // Get The Error count int eccCount = 7 * 8; if (type == 2) { eccCount = 10 * 8; } //Split error bits and message bits string errorBits = messageBits.Substring(messageBits.Length - eccCount, eccCount); messageBits = messageBits.Substring(0, messageBits.Length - eccCount); // Decode with Reed Solomon Algorithm byte[] messageBytes = BitsToByte(messageBits); byte[] errorBytes = BitsToByte(errorBits); byte[] finalMessage = ReedSolomonAlgorithm.Decode(messageBytes, errorBytes, ErrorCorrectionCodeType.QRCode); messageBits = ByteToBit(finalMessage); // Assume the image is alphanumeric and get rid of the length messageBits = messageBits.Substring(4, messageBits.Length - 4); Decode_Message(messageBits); }
/// <summary> /// transforme le message en suite de bit avec le code de correction d'erreur /// </summary> /// <param name="message"></param> /// <returns></returns> List <int> Encodage(string message) { List <int> retour = new List <int>(); int[] mode = { 0, 0, 1, 0 }; int[] taille = nombreToBinaire(message.Length, 9); int[] messageBit = stringToBit(message); foreach (int i in mode) { retour.Add(i); } foreach (int i in taille) { retour.Add(i); } foreach (int i in messageBit) { retour.Add(i); } int compteur = 0; while (retour.Count + (tailleEC * 8) < tailleTotal && compteur < 4) { retour.Add(0); compteur++; } compteur = 0; while (retour.Count % 8 != 0) { retour.Add(0); } int[] n236 = { 1, 1, 1, 0, 1, 1, 0, 0 }; int[] n17 = { 0, 0, 0, 1, 0, 0, 0, 1 }; int tailletempo = retour.Count; for (int i = 0; i < (tailleTotal - tailletempo) / 8; i++) { if (compteur % 2 == 0) { for (int j = 0; j < 8; j++) { retour.Add(n236[j]); } } else { for (int j = 0; j < 8; j++) { retour.Add(n17[j]); } } compteur++; } byte[] messageBytes = listeBitToTabByte(retour); byte[] correction = ReedSolomonAlgorithm.Encode(messageBytes, tailleEC, ErrorCorrectionCodeType.QRCode); //retour.RemoveRange(tailleTotal-(tailleEC*8), tailleEC*8); for (int i = 0; i < correction.Length; i++) { foreach (int o in nombrebyteToBinaire(correction[i], 8)) { retour.Add(o); } } if (version == 2) { for (int i = 0; i < 7; i++) { retour.Add(0); } } Console.WriteLine(retour.Count); return(retour); }