2using System.Collections.Generic;
14 private readonly
static byte[][] alignmentMarkers =
new byte[][]
22 new byte[] { 6, 22, 38 },
23 new byte[] { 6, 24, 42 },
24 new byte[] { 6, 26, 46 },
25 new byte[] { 6, 28, 50 },
26 new byte[] { 6, 30, 54 },
27 new byte[] { 6, 32, 58 },
28 new byte[] { 6, 34, 62 },
29 new byte[] { 6, 26, 46, 66 },
30 new byte[] { 6, 26, 48, 70 },
31 new byte[] { 6, 26, 50, 74 },
32 new byte[] { 6, 30, 54, 78 },
33 new byte[] { 6, 30, 56, 82 },
34 new byte[] { 6, 30, 58, 86 },
35 new byte[] { 6, 34, 62, 90 },
36 new byte[] { 6, 28, 50, 72, 94 },
37 new byte[] { 6, 26, 50, 74, 98 },
38 new byte[] { 6, 30, 54, 78, 102 },
39 new byte[] { 6, 28, 54, 80, 106 },
40 new byte[] { 6, 32, 58, 84, 110 },
41 new byte[] { 6, 30, 58, 86, 114 },
42 new byte[] { 6, 34, 62, 90, 118 },
43 new byte[] { 6, 26, 50, 74, 98 , 122 },
44 new byte[] { 6, 30, 54, 78, 102, 126 },
45 new byte[] { 6, 26, 52, 78, 104, 130 },
46 new byte[] { 6, 30, 56, 82, 108, 134 },
47 new byte[] { 6, 34, 60, 86, 112, 138 },
48 new byte[] { 6, 30, 58, 86, 114, 142 },
49 new byte[] { 6, 34, 62, 90, 118, 146 },
50 new byte[] { 6, 30, 54, 78, 102, 126, 150 },
51 new byte[] { 6, 24, 50, 76, 102, 128, 154 },
52 new byte[] { 6, 28, 54, 80, 106, 132, 158 },
53 new byte[] { 6, 32, 58, 84, 110, 136, 162 },
54 new byte[] { 6, 26, 54, 82, 110, 138, 166 },
55 new byte[] { 6, 30, 58, 86, 114, 142, 170 }
72 private int BitLengthCharacterCount(
int Version,
EncodingMode Mode)
79 else if (Version < 27)
81 else if (Version < 41)
88 else if (Version < 27)
90 else if (Version < 41)
97 else if (Version < 41)
104 else if (Version < 27)
106 else if (Version < 41)
111 throw new NotSupportedException(
"Character Count bit length not supported.");
134 int SourceIndex = Message.Length;
137 if (SourceIndex > MessageLen)
138 throw new ArgumentException(
"Message too long for selected version.", nameof(Message));
139 else if (SourceIndex < MessageLen)
141 Array.Resize(ref Message, MessageLen);
142 while (SourceIndex < MessageLen)
144 Message[SourceIndex++] = 236;
145 if (SourceIndex < MessageLen)
146 Message[SourceIndex++] = 17;
151 byte[][] DataBlocks =
new byte[d][];
157 DataBlocks[i] =
new byte[c];
158 Array.Copy(Message, SourceIndex, DataBlocks[i], 0, c);
167 DataBlocks[i] =
new byte[c];
168 Array.Copy(Message, SourceIndex, DataBlocks[i++], 0, c);
180 byte[][] ControlBlocks =
new byte[d][];
182 for (i = 0; i < d; i++)
186 int DestinationIndex = 0;
190 for (j = 0; j < d; j++)
191 Result[DestinationIndex++] = DataBlocks[j][i];
199 Result[DestinationIndex++] = DataBlocks[j][i];
207 for (j = 0; j < d; j++)
208 Result[DestinationIndex++] = ControlBlocks[j][i];
275 int Size = ((Version.Version - 1) << 2) + 21;
291 M.
VLine(7, Size - 7, Size - 1,
DotType.CodeBackground,
false);
293 M.
HLine(Size - 8, Size - 1, 7,
DotType.CodeBackground,
false);
298 if (Version.
Version > 0 && Version.
Version <= alignmentMarkers.Length)
300 byte[] Markers = alignmentMarkers[Version.Version - 1];
303 for (i = 0; i < c; i++)
305 for (j = 0; j < c; j++)
307 if ((i == 0 && (j == 0 || j == c - 1)) || (j == 0 && i == c - 1))
331 M.
HLine(Size - 8, Size - 1, 8,
DotType.CodeBackground,
false);
333 M.
VLine(8, Size - 7, Size - 1,
DotType.CodeBackground,
false);
339 for (i = 0; i < 3; i++)
341 M.
HLine(0, 5, Size - 9 - i,
DotType.CodeBackground,
false);
342 M.
VLine(Size - 9 - i, 0, 5,
DotType.CodeBackground,
false);
353 if (AssertMessageFit && !Fits)
354 throw new NotSupportedException(
"Message too long for selected QR version & error correction level.");
360 for (i = 0, c =
int.MaxValue; i < 8; i++)
374 uint u = (uint)Version.
Level;
377 u = typeInformationBits[u];
394 u = versionInformationBits[Version.Version - 7];
396 for (i = 0; i < 6; i++)
398 M.
WriteBits(u, 5 - i, Size - 9, 0, -1, 3);
399 M.
WriteBits(u, Size - 9, 5 - i, -1, 0, 3);
413 private static readonly uint[] typeInformationBits =
new uint[]
449 private static readonly uint[] versionInformationBits =
new uint[]
451 0b000111110010010100,
452 0b001000010110111100,
453 0b001001101010011001,
454 0b001010010011010011,
455 0b001011101111110110,
456 0b001100011101100010,
457 0b001101100001000111,
458 0b001110011000001101,
459 0b001111100100101000,
460 0b010000101101111000,
461 0b010001010001011101,
462 0b010010101000010111,
463 0b010011010100110010,
464 0b010100100110100110,
465 0b010101011010000011,
466 0b010110100011001001,
467 0b010111011111101100,
468 0b011000111011000100,
469 0b011001000111100001,
470 0b011010111110101011,
471 0b011011000010001110,
472 0b011100110000011010,
473 0b011101001100111111,
474 0b011110110101110101,
475 0b011111001001010000,
476 0b100000100111010101,
477 0b100001011011110000,
478 0b100010100010111010,
479 0b100011011110011111,
480 0b100100101100001011,
481 0b100101010000101110,
482 0b100110101001100100,
483 0b100111010101000001,
505 NrCharacters = Message.Length;
513 NrCharacters = Message.Length;
524 NrCharacters = ByteLen = Bin.Length;
563 throw new NotSupportedException(
"Message too large to fit in any of the recognized QR versions with the error correction level chosen.");
565 Output.WriteBits((uint)NrCharacters, this.BitLengthCharacterCount(Version.Version, Mode));
568 Encoder.Encode(Message);
571 foreach (
byte b
in Bin)
572 Output.WriteBits(b, 8);
575 ByteLen = Output.TotalBits;
576 int i = (Version.TotalDataBytes << 3) - ByteLen;
582 Output.WriteBits(0, i);
585 i = Output.TotalBits & 7;
587 Output.WriteBits(0, 8 - i);
589 i = Output.TotalBits >> 3;
590 ByteLen = Version.TotalDataBytes;
592 while (i++ < ByteLen)
594 Output.WriteBits(236, 8);
596 Output.WriteBits(17, 8);
599 return new KeyValuePair<byte[], VersionInfo>(Output.ToArray(), Version);
610 KeyValuePair<byte[], VersionInfo> P = this.
Encode(Level, Message);
Class used to compute a QR code matrix.
bool EncodeDataBits(byte[] Data)
Encodes data bits in free positions in the matrix.
void WriteBits(uint Bits, int X, int Y, int Dx, int Dy, int NrBits)
Writes bits to the matrix.
void ApplyMask(MaskFunction Mask)
Applies a mask on the matrix.
void DrawAlignmentMarker(int X, int Y)
Draws a Alignment marker pattern in the matrix.
static bool Mask4(int x, int y)
Mask function 4
static bool Mask0(int x, int y)
Mask function 0
static bool Mask6(int x, int y)
Mask function 6
int Penalty()
Calculates the total penalty score of the matrix.
void HLine(int X1, int X2, int Y, DotType Dot, bool Dotted)
Draws a horizontal line in the matrix.
static bool Mask3(int x, int y)
Mask function 3
void VLine(int X, int Y1, int Y2, DotType Dot, bool Dotted)
Draws a horizontal line in the matrix.
void DrawFinderMarker(int X, int Y)
Draws a Finder marker pattern in the matrix.
static bool Mask2(int x, int _)
Mask function 2
static bool Mask5(int x, int y)
Mask function 5
void SaveMask()
Saves the currently defined dots as a mask.
static bool Mask1(int _, int y)
Mask function 1
Implements Reed-Solomon Error Correction using polynomial division over GF(256)[x].
byte[] GenerateCorrectionCode(byte[] Message)
Computes the Error Correction code for a message.
Contains information about one version of encoding.
int BlocksPerGroup2
Blocks in Group 2
int TotalDataBytes
Total number of data bytes
int TotalBytes
Total number of bytes
int EcBytesPerBlock
Error Correction bytes per block
int TotalBlocks
Total number of blocks
int DataBytesPerBlock2
Data bytes per block in group 2
int DataBytesPerBlock1
Data bytes per block in group 1
int BlocksPerGroup1
Blocks in Group 1
int Version
Version number
CorrectionLevel Level
Error correction level.
Internal database of QR versions and properties.
static readonly VersionInfo[] QuartileVersions
Version information for Quartile Error Correction mode.
static readonly VersionInfo[] HighVersions
Version information for High Error Correction mode.
static VersionInfo FindVersionInfo(int Version, CorrectionLevel Level)
Fins information about a version and correction level.
static readonly VersionInfo[] MediumVersions
Version information for Medium Error Correction mode.
static readonly VersionInfo[] LowVersions
Version information for Low Error Correction mode.
void Dispose()
QR Code encoder.
KeyValuePair< byte[], VersionInfo > Encode(CorrectionLevel Level, string Message)
Encodes text for purposes of presenting it in the smallest QR Code matrix possible.
byte[] ApplyErrorCorrection(int Version, CorrectionLevel Level, byte[] Message)
Applies Error Correction to a byte message.
QrEncoder()
QR Code encoder.
QrMatrix GenerateMatrix(VersionInfo Version, byte[] Message)
Generates a QR Code matrix from a data message.
QrMatrix GenerateMatrix(VersionInfo Version, byte[] Message, bool ApplyErrorCorrection)
Generates a QR Code matrix from a data message.
QrMatrix GenerateMatrix(int Version, CorrectionLevel Level, byte[] Message, bool ApplyErrorCorrection)
Generates a QR Code matrix from a data message.
QrMatrix GenerateMatrix(int Version, CorrectionLevel Level, byte[] Message)
Generates a QR Code matrix from a data message.
byte[] ApplyErrorCorrection(VersionInfo Version, byte[] Message)
Applies Error Correction to a byte message.
QrMatrix GenerateMatrix(VersionInfo Version, byte[] Message, bool ApplyErrorCorrection, bool AssertMessageFit)
Generates a QR Code matrix from a data message.
QrMatrix GenerateMatrix(CorrectionLevel Level, string Message)
Generates the smallest QR Code matrix for a given data message.
Encodes alphanumeric strings
static int GetByteLength(int NrCharacters)
Gets the number of bytes required to encode an alphanumeric message containing a specific number of c...
static bool CanEncode(string Text)
Checks if a text string can be encoded using the alphanumeric encoding.
Writes a sequence of bits (Most significant bits first).
void WriteBits(uint Value, int NrBits)
Writes several bits to the output stream.
Encodes alphanumeric strings from the ISO 8859-1 character set (by default). If that fails,...
byte[] GetBytes(string Text)
Gets the byte representation of a string.
static int GetByteLength(int NrCharacters)
Gets the number of bytes required to encode an alphanumeric message containing a specific number of c...
static bool CanEncode(string Text)
Checks if a text string can be encoded using the alphanumeric encoding.
Interface for text encoders.
delegate bool MaskFunction(int x, int y)
Delegate for mask functions
CorrectionLevel
QR Code correction level.
EncodingMode
QR Code encoding mode
DotType
Type of dot in code.