.NET version: project setup and most code translated

pull/45/head
manuelbl 7 years ago
parent ec729bf269
commit 0818d857c1

4
.gitignore vendored

@ -0,0 +1,4 @@
.vs/
*.user
bin/
obj/

@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.271
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QrCodeGenerator", "QrCodeGenerator\QrCodeGenerator.csproj", "{36B0822E-28D7-43C7-BAF7-AF578E31E978}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QrCodeGeneratorTest", "QrCodeGeneratorTest\QrCodeGeneratorTest.csproj", "{81307EE7-7915-4D2D-8F71-495F239FD266}"
ProjectSection(ProjectDependencies) = postProject
{36B0822E-28D7-43C7-BAF7-AF578E31E978} = {36B0822E-28D7-43C7-BAF7-AF578E31E978}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{36B0822E-28D7-43C7-BAF7-AF578E31E978}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{36B0822E-28D7-43C7-BAF7-AF578E31E978}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36B0822E-28D7-43C7-BAF7-AF578E31E978}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36B0822E-28D7-43C7-BAF7-AF578E31E978}.Release|Any CPU.Build.0 = Release|Any CPU
{81307EE7-7915-4D2D-8F71-495F239FD266}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81307EE7-7915-4D2D-8F71-495F239FD266}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81307EE7-7915-4D2D-8F71-495F239FD266}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81307EE7-7915-4D2D-8F71-495F239FD266}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {256EFBB5-C259-4422-BE66-29B9FF4BF92F}
EndGlobalSection
EndGlobal

@ -0,0 +1,104 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using System;
using System.Collections;
namespace Io.Nayuki.QrCodeGen
{
/// <summary>
/// Provides extension methods for the <see cref="BitArray"/> class.
/// </summary>
public static class BitArrayExtensions
{
/// <summary>
/// Appends the specified number of low-order bits of the specified value to this
/// bit array. Requires 0 &#x2264; len &#x2264; 31 and 0 &#x2264; val &lt; 2<sup>len</sup>.
/// </summary>
/// <param name="bitArray">this bit array</param>
/// <param name="val">the value to append</param>
/// <param name="len">the number of low-order bits in the value to take</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the value or number of bits is out of range</exception>
/// <exception cref="InvalidOperationException">Thrown if appending the data would make bit length exceed <see cref="int.MaxValue"/></exception>
public static void AppendBits(this BitArray bitArray, uint val, int len)
{
if (len < 0 || len > 31 || (val >> len) != 0)
{
throw new ArgumentOutOfRangeException(nameof(len), "'len' out of range");
}
if (len < 0 || len > 31 || (val >> len) != 0)
{
throw new ArgumentOutOfRangeException(nameof(val), "'val' out of range");
}
int bitLength = bitArray.Length;
if (int.MaxValue - bitLength < len)
{
throw new InvalidOperationException("Maximum length reached");
}
bitArray.Length = bitLength + len;
uint mask = 1U << (len - 1);
for (int i = bitLength; i < bitLength + len; i++) // Append bit by bit
{
if ((val & mask) != 0)
{
bitArray.Set(i, true);
}
mask >>= 1;
}
}
/// <summary>
/// Appends the content of the specified bit array to this array.
/// </summary>
/// <param name="bitArray">this bit array</param>
/// <param name="otherArray">the bit array whose data to append (not <c>null</c>)</param>
/// <exception cref="ArgumentNullException">Thrown if the bit array is <c>null</c></exception>
/// <exception cref="InvalidOperationException">Thrown if appending the data would make the bit length exceed <see cref="int.MaxValue"/></exception>
public static void AppendData(this BitArray bitArray, BitArray otherArray)
{
Objects.RequireNonNull(otherArray);
int bitLength = bitArray.Length;
if (int.MaxValue - bitLength < otherArray.Length)
{
throw new InvalidOperationException("Maximum length reached");
}
bitArray.Length = bitLength + otherArray.Length;
for (int i = 0; i < otherArray.Length; i++, bitLength++) // Append bit by bit
{
if (otherArray[i])
{
bitArray.Set(bitLength, true);
}
}
}
}
}

@ -0,0 +1,58 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using System;
using System.Collections.Generic;
namespace Io.Nayuki.QrCodeGen
{
/// <summary>
/// Thrown when the supplied data does not fit any QR Code version.
/// </summary>
/// <remarks>
/// Ways to handle this exception include:
/// <ul>
/// <li>Decrease the error correction level if it was greater than <see cref="QrCode.Ecc.Low"/></li>
/// <li><p>If the advanced <see cref=QrCode.EncodeSegments(List{QrSegment}, QrCode.Ecc, int, int, int, bool)"/>
/// function or the <see cref="QrSegmentAdvanced.MakeSegmentsOptimally(string, QrCode.Ecc, int, int)"/> function was called,
/// then increase the maxVersion argument if it was less than <see cref="QrCode.MaxVersion"/>.
/// (This advice does not apply to the other factory functions because they search all versions up to
/// <see cref="QrCode.MaxVersion"/></li>
/// <li>Split the text data into better or optimal segments in order to reduce the number of bits required.
/// (See <see cref="QrSegmentAdvanced.MakeSegmentsOptimally(string, QrCode.Ecc, int, int)"/>.)</li>
/// <li>Change the text or binary data to be shorter.</li>
/// <li>Change the text to fit the character set of a particular segment mode (e.g. alphanumeric).</li>
/// <li>Propagate the error upward to the caller/user.</li>
/// </ul>
/// </remarks>
/// <seealso cref="QrCode.EncodeText(string, QrCode.Ecc)"/>
/// <seealso cref="QrCode.EncodeBinary(byte[], QrCode.Ecc)"/>
/// <seealso cref="QrCode.EncodeSegments(List{QrSegment}, QrCode.Ecc)"/>
/// <seealso cref="QrCode.EncodeSegments(List{QrSegment}, QrCode.Ecc, int, int, int, bool)"/>
/// <seealso cref="QrSegmentAdvanced.MakeSegmentsOptimally(string, QrCode.Ecc, int, int)"/>
public class DataTooLongException : ArgumentException
{
public DataTooLongException(string message)
: base(message)
{ }
}
}

@ -0,0 +1,39 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using System;
namespace Io.Nayuki.QrCodeGen
{
internal class Objects
{
internal static T RequireNonNull<T>(T arg)
{
if (arg == null)
{
throw new ArgumentNullException();
}
return arg;
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Io.Nayuki.QrCodeGen</RootNamespace>
<PackageId>Io.Nayuki.QrCodeGen</PackageId>
<Version>1.4.1</Version>
<Authors>Project Nayuki</Authors>
<Product>QR Code Generator for .NET</Product>
<Description>This project aims to be the best, clearest QR Code generator library in multiple languages. The primary goals are flexible options and absolute correctness. Secondary goals are compact implementation size and good documentation comments</Description>
<Copyright>Copyright (c) Project Nayuki. (MIT License)</Copyright>
<RepositoryUrl>https://github.com/nayuki/QR-Code-generator</RepositoryUrl>
<PackageProjectUrl>https://www.nayuki.io/page/qr-code-generator-library</PackageProjectUrl>
<PackageLicenseUrl>https://opensource.org/licenses/MIT</PackageLicenseUrl>
<PackageTags>qr code, qrcode</PackageTags>
<PackageReleaseNotes>Initial release for .NET</PackageReleaseNotes>
</PropertyGroup>
</Project>

@ -0,0 +1,379 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
namespace Io.Nayuki.QrCodeGen
{
/// <summary>
/// A segment of character/binary/control data in a QR Code symbol.
/// </summary>
/// <remarks>
/// <para>Instances of this class are immutable.</para>
/// <para>The mid-level way to create a segment is to take the payload data and call a
/// static factory function such as <see cref="MakeNumeric(string)"/>. The low-level
/// way to create a segment is to custom-make the bit buffer and call the
/// <see cref="QrSegment(Mode, int, BitArray)"/> with appropriate values.</para>
/// <para>This segment class imposes no length restrictions, but QR Codes have restrictions.
/// Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
/// Any segment longer than this is meaningless for the purpose of generating QR Codes.
/// This class can represent kanji mode segments, but provides no help in encoding them
/// - see <see cref="QrSegmentAdvanced"/> for full kanji support.</para>
/// </remarks>
public class QrSegment
{
#region Static factory functions (mid level)
/// <summary>
/// Returns a segment representing the specified binary data
/// encoded in byte mode. All input byte arrays are acceptable.
/// </summary>
/// <remarks>
/// Any text string can be converted to UTF-8 bytes (<c>Encoding.UTF8.GetBytes(s)</c>)
/// and encoded as a byte mode segment.
/// </remarks>
/// <param name="data">the binary data (not <c>null</c>)</param>
/// <returns>a segment (not <c>null</c>) containing the data</returns>
/// <exception cref="ArgumentNullException">Thrown if the array is <c>null</c></exception>
public static QrSegment MakeBytes(byte[] data)
{
Objects.RequireNonNull(data);
BitArray ba = new BitArray(0);
foreach (byte b in data)
{
ba.AppendBits(b, 8);
}
return new QrSegment(Mode.Byte, data.Length, ba);
}
/// <summary>
/// Returns a segment representing the specified string of decimal digits encoded in numeric mode.
/// </summary>
/// <param name="digits">the text (not <c>null</c>), with only digits from 0 to 9 allowed</param>
/// <returns>a segment (not <c>null</c>) containing the text</returns>
/// <exception cref="ArgumentNullException">Thrown if the string is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the string contains non-digit characters</exception>
public static QrSegment MakeNumeric(string digits)
{
Objects.RequireNonNull(digits);
if (!NumericRegex.IsMatch(digits))
{
throw new ArgumentOutOfRangeException(nameof(digits), "String contains non-numeric characters");
}
BitArray ba = new BitArray(0);
for (int i = 0; i < digits.Length;)
{
// Consume up to 3 digits per iteration
int n = Math.Min(digits.Length - i, 3);
ba.AppendBits(uint.Parse(digits.Substring(i, n)), n * 3 + 1);
i += n;
}
return new QrSegment(Mode.Numeric, digits.Length, ba);
}
/// <summary>
/// Returns a segment representing the specified text string encoded in alphanumeric mode.
/// The characters allowed are: 0 to 9, A to Z(uppercase only), space,
/// dollar, percent, asterisk, plus, hyphen, period, slash, colon.
/// </summary>
/// <param name="text">the text (not <c>null</c>), with only certain characters allowed</param>
/// <returns>a segment (not <c>null</c>) containing the text</returns>
/// <exception cref="ArgumentNullException">Thrown if the string is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown iif the string contains non-encodable characters</exception>
public static QrSegment MakeAlphanumeric(string text)
{
Objects.RequireNonNull(text);
if (!AlphanumericRegex.IsMatch(text))
{
throw new ArgumentOutOfRangeException(nameof(text), "String contains unencodable characters in alphanumeric mode");
}
BitArray ba = new BitArray(0);
int i;
for (i = 0; i <= text.Length - 2; i += 2)
{
// Process groups of 2
uint temp = (uint)AlphanumericCharset.IndexOf(text[i]) * 45;
temp += (uint)AlphanumericCharset.IndexOf(text[i + 1]);
ba.AppendBits(temp, 11);
}
if (i < text.Length) // 1 character remaining
{
ba.AppendBits((uint)AlphanumericCharset.IndexOf(text[i]), 6);
}
return new QrSegment(Mode.Alphanumeric, text.Length, ba);
}
/// <summary>
/// Returns a list of zero or more segments to represent the specified Unicode text string.
/// The result may use various segment modes and switch modes to optimize the length of the bit stream.
/// </summary>
/// <param name="text">the text to be encoded, which can be any Unicode string</param>
/// <returns>a new mutable list (not <c>null</c>) of segments (not <c>null</c>) containing the text</returns>
/// <exception cref="ArgumentNullException">Thrown if the text is <c>null</c></exception>
public static List<QrSegment> MakeSegments(string text)
{
Objects.RequireNonNull(text);
// Select the most efficient segment encoding automatically
List<QrSegment> result = new List<QrSegment>();
if (text == "")
{
// Leave result empty
}
else if (NumericRegex.IsMatch(text))
{
result.Add(MakeNumeric(text));
}
else if (AlphanumericRegex.IsMatch(text))
{
result.Add(MakeAlphanumeric(text));
}
else
{
result.Add(MakeBytes(Encoding.UTF8.GetBytes(text)));
}
return result;
}
/// <summary>
/// Returns a segment representing an Extended Channel Interpretation
/// (ECI) designator with the specified assignment value.
/// </summary>
/// <param name="assignVal">the ECI assignment number (see the AIM ECI specification)</param>
/// <returns>a segment (not <c>null</c>) containing the data</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the value is outside the range [0, 10<sup>6</sup>)</exception>
public static QrSegment MakeEci(int assignVal)
{
BitArray ba = new BitArray(0);
if (assignVal < 0)
{
throw new ArgumentOutOfRangeException(nameof(assignVal), "ECI assignment value out of range");
}
if (assignVal < (1 << 7))
{
ba.AppendBits((uint)assignVal, 8);
}
else if (assignVal < (1 << 14))
{
ba.AppendBits(2, 2);
ba.AppendBits((uint)assignVal, 14);
}
else if (assignVal < 1_000_000)
{
ba.AppendBits(6, 3);
ba.AppendBits((uint)assignVal, 21);
}
else
{
throw new ArgumentOutOfRangeException(nameof(assignVal), "ECI assignment value out of range");
}
return new QrSegment(Mode.Eci, 0, ba);
}
#endregion
#region Instance fields
/// <summary>
/// The mode indicator of this segment. Not <c>null</c>.
/// </summary>
public Mode EncodingMode { get; }
/// <summary>
/// The length of this segment's unencoded data. Measured in characters for
/// numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
/// Always zero or positive. Not the same as the data's bit length.
/// </summary>
public int NumChars { get; }
// The data bits of this segment. Not null. Accessed through GetData().
private readonly BitArray _data;
#endregion
#region Constructor (low level)
/// <summary>
/// Constructs a QR Code segment with the specified attributes and data.
/// The character count(numCh) must agree with the mode and the bit buffer length,
/// but the constraint isn't checked. The specified bit buffer is cloned and stored.
/// </summary>
/// <param name="md">the mode (not <c>null</c>)</param>
/// <param name="numCh">the data length in characters or bytes, which is non-negative</param>
/// <param name="data">the data bits (not <c>null</c>)</param>
/// <exception cref="ArgumentNullException">Thrown if the mode or data is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the character count is negative</exception>
public QrSegment(Mode md, int numCh, BitArray data)
{
EncodingMode = Objects.RequireNonNull(md);
Objects.RequireNonNull(data);
if (numCh < 0)
{
throw new ArgumentOutOfRangeException(nameof(numCh), "Invalid value");
}
NumChars = numCh;
_data = (BitArray)data.Clone(); // Make defensive copy
}
#endregion
#region Methods
/// <summary>
/// Returns the data bits of this segment.
/// </summary>
/// <returns>a new copy of the data bits(not<c>null</c>)</returns>
public BitArray GetData()
{
return (BitArray)_data.Clone(); // Make defensive copy
}
// Calculates the number of bits needed to encode the given segments at the given version.
// Returns a non-negative number if successful. Otherwise returns -1 if a segment has too
// many characters to fit its length field, or the total bits exceeds int.MaxValue.
internal static int GetTotalBits(List<QrSegment> segs, int version)
{
Objects.RequireNonNull(segs);
long result = 0;
foreach (QrSegment seg in segs)
{
Objects.RequireNonNull(seg);
int ccbits = seg.EncodingMode.NumCharCountBits(version);
if (seg.NumChars >= (1 << ccbits))
{
return -1; // The segment's length doesn't fit the field's bit width
}
result += 4L + ccbits + seg._data.Length;
if (result > int.MaxValue)
{
return -1; // The sum will overflow an int type
}
}
return (int)result;
}
#endregion
#region Constants
/// <summary>
/// Describes precisely all strings that are encodable in numeric mode.
/// </summary>
/// <remarks>
/// To test whether a string <c>s</c> is encodable:
/// <code>
/// bool ok = NumericRegex.IsMatch(s);
/// </code>
/// A string is encodable iff each character is in the range 0 to 9.
/// </remarks>
/// <seealso cref="MakeNumeric(string)"/>
public static readonly Regex NumericRegex = new Regex("^[0-9]*$", RegexOptions.Compiled);
/// <summary>
/// Describes precisely all strings that are encodable in alphanumeric mode.
/// </summary>
/// <remarks>
/// To test whether a string <c>s</c> is encodable:
/// <code>
/// bool ok = AlphanumericRegex.IsMatch(s);
/// </code>
/// A string is encodable iff each character is in the following set: 0 to 9, A to Z
/// (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
/// </remarks>
/// <seealso cref="MakeAlphanumeric(string)"/>
public static readonly Regex AlphanumericRegex = new Regex("^[A-Z0-9 $%*+./:-]*$", RegexOptions.Compiled);
// The set of all legal characters in alphanumeric mode, where
// each character value maps to the index in the string.
static readonly string AlphanumericCharset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
#endregion
#region Public helper enumeration
/// <summary>
/// Describes how a segment's data bits are interpreted.
/// </summary>
public sealed class Mode
{
public static readonly Mode Numeric = new Mode(0x1, 10, 12, 14);
public static readonly Mode Alphanumeric = new Mode(0x2, 9, 11, 13);
public static readonly Mode Byte = new Mode(0x4, 8, 16, 16);
public static readonly Mode Kanji = new Mode(0x8, 8, 10, 12);
public static readonly Mode Eci = new Mode(0x7, 0, 0, 0);
// The mode indicator bits, which is a uint4 value (range 0 to 15).
internal uint ModeBits { get; }
// Number of character count bits for three different version ranges.
internal int[] NumBitsCharCount { get; }
// Returns the bit width of the character count field for a segment in this mode
// in a QR Code at the given version number. The result is in the range [0, 16].
internal int NumCharCountBits(int ver)
{
Debug.Assert(QrCode.MinVersion <= ver && ver <= QrCode.MaxVersion);
return NumBitsCharCount[(ver + 7) / 17];
}
private Mode(uint modeBits, params int[] numBitsCharCount)
{
ModeBits = modeBits;
NumBitsCharCount = numBitsCharCount;
}
}
#endregion
}
}

@ -0,0 +1,144 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using System;
using System.Diagnostics;
namespace Io.Nayuki.QrCodeGen
{
/// <summary>
/// Computes the Reed-Solomon error correction codewords for a sequence of data codewords at a given degree.
/// </summary>
/// <remarks>
/// Objects are immutable, and the state only depends on the degree.
/// This class exists because each data block in a QR Code shares the same the divisor polynomial.
/// </remarks>
internal class ReedSolomonGenerator
{
#region Fields
// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
private readonly byte[] _coefficients;
#endregion
#region Constructors
/// <summary>
/// Constructs a Reed-Solomon ECC generator for the specified degree. This could be implemented
/// as a lookup table over all possible parameter values, instead of as an algorithm.
/// </summary>
/// <param name="degree">the divisor polynomial degree, which must be between 1 and 255 (inclusive)</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if degree &lt; 1 or degree > 255</exception>
internal ReedSolomonGenerator(int degree)
{
if (degree < 1 || degree > 255)
{
throw new ArgumentOutOfRangeException(nameof(degree), "Degree out of range");
}
// Start with the monomial x^0
_coefficients = new byte[degree];
_coefficients[degree - 1] = 1;
// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
// drop the highest term, and store the rest of the coefficients in order of descending powers.
// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
uint root = 1;
for (int i = 0; i < degree; i++)
{
// Multiply the current product by (x - r^i)
for (int j = 0; j < _coefficients.Length; j++)
{
_coefficients[j] = Multiply(_coefficients[j], root);
if (j + 1 < _coefficients.Length)
{
_coefficients[j] ^= _coefficients[j + 1];
}
}
root = Multiply(root, 0x02);
}
}
#endregion
#region Methods
/// <summary>
/// Computes and returns the Reed-Solomon error correction codewords for the specified
/// sequence of data codewords.
/// </summary>
/// <remarks>
/// The returned object is always a new byte array.
/// This method does not alter this object's state (because it is immutable).
/// </remarks>
/// <param name="data">the sequence of data codewords</param>
/// <returns>the Reed-Solomon error correction codewords</returns>
/// <exception cref="ArgumentNullException">Thrown if the data is <c>null</c></exception>
internal byte[] GetRemainder(byte[] data)
{
Objects.RequireNonNull(data);
// Compute the remainder by performing polynomial division
byte[] result = new byte[_coefficients.Length];
foreach (byte b in data)
{
uint factor = (uint)(b ^ result[0]);
Array.Copy(result, 1, result, 0, result.Length - 1);
result[result.Length - 1] = 0;
for (int i = 0; i < result.Length; i++)
{
result[i] ^= Multiply(_coefficients[i], factor);
}
}
return result;
}
#endregion
#region Static functions
// Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
// are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
private static byte Multiply(uint x, uint y)
{
Debug.Assert((x >> 8) == 0 && (y >> 8) == 0);
// Russian peasant multiplication
uint z = 0;
for (int i = 7; i >= 0; i--)
{
z = (z << 1) ^ ((z >> 7) * 0x11D);
z ^= ((y >> i) & 1) * x;
}
Debug.Assert((z >> 8) == 0);
return (byte)z;
}
#endregion
}
}

@ -0,0 +1,79 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using System;
using System.Collections;
using Xunit;
namespace Io.Nayuki.QrCodeGen.Test
{
public class BitArrayExtensionsTest
{
[Fact]
private void AppendInt1()
{
var ba = new BitArray(0);
ba.AppendBits(18, 6);
Assert.Equal(6, ba.Length);
Assert.False(ba[0]);
Assert.True(ba[1]);
Assert.False(ba[2]);
Assert.False(ba[3]);
Assert.True(ba[4]);
Assert.False(ba[5]);
}
[Fact]
private void AppendInt2()
{
var ba = new BitArray(0);
ba.AppendBits(18, 6);
ba.AppendBits(3, 2);
Assert.Equal(8, ba.Length);
Assert.False(ba[0]);
Assert.True(ba[1]);
Assert.False(ba[2]);
Assert.False(ba[3]);
Assert.True(ba[4]);
Assert.False(ba[5]);
Assert.True(ba[6]);
Assert.True(ba[7]);
}
[Fact]
private void AppendExtraBits()
{
var ba = new BitArray(0);
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
ba.AppendBits(128, 4);
});
}
}
}

@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>false</IsPackable>
<RootNamespace>Io.Nayuki.QrCodeGen.Test</RootNamespace>
<PackageId>Io.Nayuki.QrCodeGen.Test</PackageId>
<Version>1.4.1</Version>
<Authors>Project Nayuki</Authors>
<Company>Project Nayuki</Company>
<Product>QR Code Generator for .NET</Product>
<Description>Unit tests for QR Code Generator</Description>
<Copyright>Copyright (c) Project Nayuki. (MIT License)</Copyright>
<PackageLicenseUrl>https://opensource.org/licenses/MIT</PackageLicenseUrl>
<PackageProjectUrl>https://www.nayuki.io/page/qr-code-generator-library</PackageProjectUrl>
<RepositoryUrl>https://github.com/nayuki/QR-Code-generator</RepositoryUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\QrCodeGenerator\QrCodeGenerator.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,930 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using System.Text;
using Xunit;
using static Io.Nayuki.QrCodeGen.QrCode;
namespace Io.Nayuki.QrCodeGen.Test
{
public class QrCodeTest
{
private static readonly string[] Modules0 = {
"XXXXXXX X XXXXXXX",
"X X XX X X X",
"X XXX X X X XXX X",
"X XXX X XX X X XXX X",
"X XXX X X X XXX X",
"X X XXXX X X",
"XXXXXXX X X X XXXXXXX",
" X X ",
" XXXX XX XX X ",
" X XX XX XXX X X ",
" XXX XX XXXXXXXX ",
"X X X X X X X X XX ",
"X XXXX XX ",
" X X XX X ",
"XXXXXXX X X X X ",
"X X XXXXXXXX X X ",
"X XXX X XX XXX XX XXX",
"X XXX X XXXX X X XX",
"X XXX X X X XXXX ",
"X X X X X XX ",
"XXXXXXX X X X XXX"
};
private const string Text0 = "98323";
[Fact]
private void TestCode0()
{
var qrCode = EncodeText(Text0, Ecc.Medium);
Assert.Same(Ecc.High, qrCode.ErrorCorrectionLevel);
Assert.Equal(21, qrCode.Size);
Assert.Equal(4, qrCode.Mask);
Assert.Equal(Modules0, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules1 = {
"XXXXXXX X X XXX X XXXXXXX",
"X X X X XXX XX X X",
"X XXX X XXXX X X X X XXX X",
"X XXX X X XX XX XX X XXX X",
"X XXX X X XXX X X XXX X",
"X X X X X XX X X",
"XXXXXXX X X X X X X X XXXXXXX",
" X XX XX X ",
" XX X XX XXX X X X XXXXX",
" XXX XXXXXXXXX X XXXX XXX",
" XXXX XXXX XXXXXXXXXXXX XX",
"XXX XXX X XX X X X ",
"X X XX X XXXX XX XXXXX X XX",
" XX XX X XX X XX XXXX",
"X X X X XX X X X XX XXX",
"X X XX XXX X XXX X XX",
"X XXXXX XX X X XXXXXX XX",
" XXX XXX X XX XX X XX ",
"X XXX X XXXX XXX",
" XXX X X XX X XXX XXX ",
"X XX XX X XXX XXX XXXXX ",
" XX X XX XXX X XX",
"XXXXXXX X X XX XX X XXXXX",
"X X X X XX X X XX X ",
"X XXX X X XXXXXX XXXXX X",
"X XXX X X X X X X XX ",
"X XXX X X X X X X XX X X",
"X X X X XXX XX XX X X ",
"XXXXXXX XX X XX XX X X XX"
};
private const string Text1 = "The quick brown fox jumps";
[Fact]
private void TestCode1()
{
var qrCode = EncodeText(Text1, Ecc.Quartile);
Assert.Same(Ecc.Quartile, qrCode.ErrorCorrectionLevel);
Assert.Equal(29, qrCode.Size);
Assert.Equal(0, qrCode.Mask);
Assert.Equal(Modules1, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules2 = {
"XXXXXXX XXXXX X XX X X XXX X XXX X X XX XXXXXXX",
"X X XX XXXXX XX XXXX X XX XXX XXX X XX X X",
"X XXX X X X XXXXX XX XX XXX X XX XXX X XXX X XXX X",
"X XXX X XX X X X X XXX X XX XX X X XX XX X X XXX X",
"X XXX X X X XX X XX X X XXXXXX X XXXX X X XX X XXX X",
"X X XXXX XXX XX XX X X XX X XX XX X XXXX X X",
"XXXXXXX X X X X X X X X X X X X X X X X X X X X X X X XXXXXXX",
" X X XXXXX XXX XXXX X XXXX XXX XXX X ",
"X X XXX XXX XXXXX X XXXXX XXX X X X XX XXXXX X",
"XXXX X X X X XX X X XX X XXXX XXXX X ",
" X XX X X X X X XXXX X XXX X X XXX X X X X X X XX ",
"X XXX X XX X XXX X X X X X X XXX XX XXXX X XX ",
"XX X XXX XXXXXXX XX XXX X XXXX X X X XX XXX X X X X ",
"X X X XXXX X X XX XX X XX XXXXX XX XX X XX ",
" X XX XX X XXXX XXX XXXX X X X XXX XX X XX XXX X ",
"X XX X XXXX X X X X X X X XXXX XX XXXX X ",
"XX X X XXX X XX XXXXX X X X XXXX X XXXXXXXXX X XXX",
"X X XXXXX XX XXX X XXX X X XXXX X XXX XX X ",
"X XXX XX XXX X XX XXX XXX X X X XXXXX XXXX XX ",
"XX X X XX XXX XXXX XX XX XX XXX XX XX ",
" XXX X X X X X X X XX X XXXXXXXXX XX X XX XX XX X ",
"X X X X X XXX XXX XXXX XXXX X X XXX X X XX XX X X ",
" XX X X XXX XXXXXX XX X X XX X XXX X XX XX X ",
" XX X XXXX X XX X X XX X X XXXX X XXXXXX X X X ",
"XX XXXX X XXX XX X X XXXX XXXX X XX XX X XXXXX",
" X XX XXXXXXXXXXX XXX X XX X XXX X X XXX XX XX XX XXX X",
"XXXXX X X X XXX X XX XX XXX XX X XX X X X ",
"X X X X X X X X XXXXX X X XX X XXX X XX X X X",
" X XXXXXX X XXX X X XXXXX XX X XX XXXX XXXXX XXX",
" XXX X XXX XX XX XXX X XX X XXXXX XXX XX XX",
"XXXXX X X X X XX XX X XX X X XXXX XXXX XXXX X X X X ",
" X X X XX X X X XXXXX X XXXXX XX X XXX X X ",
" XXXXXX XX XXXXX XX X XXXXX X X XX XXX XXXXX XXX",
"X X X X XX X X X XXXXX XXXX X XXXXXXXX X XX XX XX ",
" X XXXXX X XXXXX X X X XXX X XX X XXX X ",
"X XXX X XXX X XXXXX X XX XXX X XX X X XXX XX XXXX",
" XX X XX X X XXXXXXX XX X XX X X XXXXXXXX X XX XX X",
"XX X X XX X X X XX XX XX XX XX XX XX X X X X XX XX",
" X XX X X XXXXX XXX XX X XX XXX XXXXX X XX X X XX X",
"XX X XX XXXXX XXX X X X X XX XXXXX XXX XX ",
" XXXX X XX XXX XXXXXX XX XXXXXX X X X XXX X X XX X",
"XXXX X XX XXX X XXX X X X X XX X XX XX X X XXX XX X ",
" XXXXXX XXX X XX X XX XX X XXX X X XX XXXX ",
" XXXX XXX XX XXX X X XXXX X XXX X X X X XXX",
" XX XXXX X X X X XX X X XXXXXX X X XXXX XXXX XXX XXX X",
"XX XX XXX XX XXXXXXX X X XXXX X X X XX X XXXX ",
" XX XXX X XXXX X X X X XXX XX X X X XXX XX XX XX ",
" XX X X XXX XXXX X X XXXXX XXXX X XXXX X X XX XX ",
"XXX XX X XX XXXX X XX XX XXXXX X X XX X X ",
"XX XX X XX XXXX X X XX XX XXXX X XX XX XX X X XX X ",
" XXXXXX X X XXXX XXXXXX X X XX XXXX XX XX ",
"XXX X XXX X XX XX XX XXX XXXXX XXX X XXX XX X X X XXX ",
"XXXX XXX XXX X X X XXXXX X X XX XXXX XXXXX X X",
" XXXX XXXX X XXXXXX X XX X X XXXXX X X X X ",
"XXXXXXX X X XXX X X X X X X XXX XXXX XXXXXX XXX X XX ",
"X X XX XX XXXXX X X X XX X X XXXX X XXX XX X X ",
"X XXX X X X XX X XX XX XXXXX X XXX X XXX XXXXX XX",
"X XXX X X X XX XX XX XXX X XX XXXX X X X X",
"X XXX X X X X XX XXX X XXX X X XXXX XX XX X XXX ",
"X X X XXX X XXXX XX X XXXX XXX XXXXX XX XX XX XX ",
"XXXXXXX X X X X X X X XX X XXX XX X XXX"
};
private const string Text2 = "kVtnmdZMDB wbhQ4Y0L0D 6dxWYgeDO7 6XEq8JBGFD dbA5ruetw0 zIevtZZkJL UnEcrObNuS COOscwe4PD PL2lKGcbqk uXnmfUX00E l4FsUfvkiU O8bje4GTce C85HiEHDha EoObmX7Hef VEipzaCPV7 XpBy5cgYRZ VzlrmMTRSW f0U7Dt0x5j Mb5uk2JcA6 MFov2hnHQR";
[Fact]
private void TestCode2()
{
var qrCode = EncodeText(Text2, Ecc.Medium);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(61, qrCode.Size);
Assert.Equal(4, qrCode.Mask);
Assert.Equal(Modules2, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules3 = {
"XXXXXXX X X XXXX XXXXXXX",
"X X X X X X X",
"X XXX X X X X XXX X XXX X",
"X XXX X X X XX XX X XXX X",
"X XXX X X X X X XXX X",
"X X X XX X X X",
"XXXXXXX X X X X X XXXXXXX",
" X X X ",
" X X XXXX XX XX XXX XX X",
"XXX X XX X X X XXX ",
" X X XXXX XXXX XXX ",
" X X XX XX X XXXXXXXX",
" XXXXX X XX X XX ",
" X XX X X XX XX XX ",
"X XX XX XXX X XXX XX ",
" X X X XX XXX XX XX X ",
"XX X X X XXXX XXXXX X X",
" XX XX XX XX XX",
"XXXXXXX XXX X XX X X XX ",
"X X X XX XXXX X XX",
"X XXX X XXXX X XXXXX XX",
"X XXX X X XX XX XXXX ",
"X XXX X XXX XX X X",
"X X X X X X X XX ",
"XXXXXXX X X X X XXX"
};
private const string Text3 = "😀 € éñ 💩";
[Fact]
private void TestCode3()
{
var qrCode = EncodeBinary(Encoding.UTF8.GetBytes(Text3), Ecc.Low);
Assert.Same(Ecc.Quartile, qrCode.ErrorCorrectionLevel);
Assert.Equal(25, qrCode.Size);
Assert.Equal(7, qrCode.Mask);
Assert.Equal(Modules3, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules4 = {
"XXXXXXX XX X X XXX XX XXX XXX X X XX XXXXXXX",
"X X XXX X XXX X X XX XXX X X X X X X",
"X XXX X XX XX XX XX X XXX XXXX X XXXXXX X XXX X XXX X",
"X XXX X XX X X XX X XX X X X X X X XXX X",
"X XXX X XXX X X XX XXXXXX XX X X X X X X XXX X",
"X X X XX XXX X XX X XX XX XXXXXXXXXX X X",
"XXXXXXX X X X X X X X X X X X X X X X X X X X X X XXXXXXX",
" X X X X X X X X XXXX XX X X XXX ",
" XXXX XXX XX XXXXX XXXXXX XXX X X XX X ",
" X X X X XX XXX X X X X X XX X",
"XXXXXXXXXXX XXXX X X X XX X X XXX XXX XX XXX XX ",
"X X X X X X XX XXX XX X XX XXX X X XX XX ",
" X X X XXX XX XXXXXXXXXXX X XXXXX XXX X X XXX",
" XX XX XXX X X XX XXX XXXX XX X XX XXX XXX",
" XX X XX X X X X X XX XXX XXX XXXX X X XX",
" X X XX X XXXXX XXXXX XXX XX X XX XXX XXXXX X",
"X XXX XXXX XXX X XXXXXX XX XXX XXX XX XXXX ",
" X X X X XX X XX X X X X X X X XX X",
" XX X XXXXX X X X X X XXX XXX XXX XXX XXX XX ",
" XX X X X XXX XXXXXX X X XX XXX X XX XX ",
"X XX X XX X X XXXXXXXXX XXXXX XXX XXX XXX",
"XXXX X XX XX XX X X X X XXX XX X XX XX XXX XX X ",
" XX XXXX XXX X XXX XX XXX XXX XXXX X XX ",
" X XX X XX XX X X XXXXXXX XX XX X XXX XX X XX ",
"XXXXXXXXXX X X X X X XX XX XXX XXXXX XX XXX",
" XX XX X XXXX X XX XX X XX X X X X X X XX X",
" XX XXXXXXX XX XX X XXXXX X XXX XX XXXXXXX X ",
" XX X XX X XXXX X XXXXXX X X X X X X XX X ",
"X X X XX XXXXX X X XXXX X X XX X X XXX X XX XX",
"XXXXX X X X X X XX XX XXX X X XXXX XX X",
" XX XXXXXXX X XX X X XXXXXXX X XXX XXX XXXX XXXXXXX ",
" XXX X XX XXX XX XXX XXX X XXXXX X XXX XX XX ",
"XXX XX XXXXX X X XX XX XXX XX XXXXXXX XX XXX",
" X X XX X XXXX X X X X X X X XXX XXX",
" XXX XXX XX X XXXX XX X X XX X XX X XX X XX",
" X XX XX XXXXXXXX XXXX XX XX X X X X XXX X X",
"X X X XXXXX X X XXXXXXXX XX X X X XXXXXX XX ",
"XXX XX X X X X X XX XX XXXX X X XXX X X X",
" XX XX XX X X X XXX XXX X XX XXX XXXX XXX ",
"X XXX XX XX XXX XX XX XXX X XXX X XXX XX XX ",
" X X X XXX X X XXXX X XX XXXX XXXXXXX XXX X XXX",
" XX X X X X X XX X XXX X X XX X X XXXX XXX XXX",
" XX XXX XXX XXXX X X X X XX X X XX XXXX XX",
"X XX XX X XX XXXXXXX XX XX X XXX X XX XXX X X",
" X XX XX XXXXX XX X XX X XX X X XX XX XXX XX ",
" X XXX X XX XX XXX X XXX X X X X X X X X",
"X X XXX XXX XX XXX X XXX X XX XXX XXX XXX ",
"XXXXX XXXXX XXXXX X XXX XXXXXX XXX XX XX ",
" X XXXX XX X X XXXXXXXX XXXXX XXXX XXXXXXX XXX",
" XX X X XXX X X X X XX XX X X XXX",
"XXXXXXX XXXX XXX XX X X XXXX X XXXX X X X XX",
"X X X X X XXXXX XX XXXX X X X XX XX X XX X",
"X XXX X X XXX X X X X XXXXXXXXX X X XXX XXXXXXXX ",
"X XXX X XX XXXXX X XXXXX XX X X X XX X XXX",
"X XXX X XXX X X X XX XXXXXXX XXX XX XXX XX XXX ",
"X X XXXXX X XXXXX X XX X XX X XX X XX XX X",
"XXXXXXX XX X X XX X XX X XXXXXX XX X XXXX XXXX"
};
private const string Text4 = "ABCD22340";
[Fact]
private void TestCode4()
{
var segments = QrSegment.MakeSegments(Text4);
var qrCode = EncodeSegments(segments, Ecc.High, 10, 40, 4, false);
Assert.Same(Ecc.High, qrCode.ErrorCorrectionLevel);
Assert.Equal(57, qrCode.Size);
Assert.Equal(4, qrCode.Mask);
Assert.Equal(Modules4, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules5 = {
"XXXXXXX X X XXXXXXX",
"X X X X XXX X X X",
"X XXX X X XXX X XXX X",
"X XXX X XX XXX X X XXX X",
"X XXX X X XXXX X XXX X",
"X X X X X X X",
"XXXXXXX X X X X X XXXXXXX",
" X XXX X ",
"X XX XXX X X XX X X XX",
" XX X XXXX X XX XX ",
"XXX XX XX XXX X X ",
"X X X X X X X X X",
" X XX XX X X X X X X",
" X X XXXX X X XX XXX",
" XXXX X X X X X XX XXX X",
"X X XXXX XXX XXXXX X ",
" XX XXXXXX X XXXXXX X ",
" X X XX XX X X ",
"XXXXXXX XXXXX X X X X ",
"X X XXX X X X X XX ",
"X XXX X X XXX XXXXXXX XX",
"X XXX X XX XX X X X X",
"X XXX X XX XXX XXXX XX X ",
"X X X XXX XX ",
"XXXXXXX X X XX XXX X X"
};
private const string Text5 = "314159265358979323846264338327950288419716939937510";
[Fact]
private void TestCode5()
{
var qrCode = EncodeText(Text5, Ecc.Medium);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(25, qrCode.Size);
Assert.Equal(3, qrCode.Mask);
Assert.Equal(Modules5, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules6 = {
"XXXXXXX X XX XX XXXXXX XXXXXXX",
"X X XX XX XXX X XXX X X X",
"X XXX X X XXX X XXXXX X X XXX X",
"X XXX X X XXX X X X XX X XXX X",
"X XXX X X XX XXX X X X XXX X",
"X X X XXX XXXXXXX XX XXX X X",
"XXXXXXX X X X X X X X X X X X XXXXXXX",
" X X X X X X XX ",
" X XXXX XXXXX XX X X X X XXXXX ",
" XX XX X XX XX XX X ",
" XXXXX XXXX X X XX X XX X X XX",
" X XXXXX XXX XX XXX XXX X X ",
"X XX XXXXXXX XX XX X XX XXX XX",
"XXX X X X XX XXX X XXX X X ",
" XX X XX X XXXXXXX X XXX XXX XXX XX",
"XX XX X X X XXX X X X XXXX X",
"X X XXXXXX X XXXXXX X XXXXX X X XXX",
" X XXX X X XXX X X X X X X",
" X XX XX X X XXX X XXXXX X ",
"X X XX X X X X XXXXXX",
" XXXXXXXXX X XXX X X X X XX X ",
"XX X X X X XXXX X X XXXXX ",
"XXX XXXX X X XX XXXXX X XXX X",
"XXX XX XXXX XXX XXXX X X XX XXXXXXX ",
"XXX X X X XXXX XXX XX XXX X XXX",
" XX XXX XXX X X X X XXXXX ",
"XX XX X XXX X X XX X XX X X",
" XX XXXX X XX X XXXX XXXX ",
"XXXXXXX X XXX XX X XXXXX XXXXXXXX ",
" X X X XXX XXXXX XXX XX ",
"XXXXXXX X XX X XXX X XX X X X",
"X X X X XX X X X X X XXX",
"X XXX X X X X XXX X XX XXXXXXX X",
"X XXX X XX X XXX X X X XXXX X ",
"X XXX X XXX X X X X X XX XX",
"X X XXXX X XX XX X X XX X",
"XXXXXXX XXX XX XXXX X XXXX XXX"
};
private const string Text6 = "DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/";
[Fact]
private void TestCode6()
{
var qrCode = EncodeText(Text6, Ecc.High);
Assert.Same(Ecc.High, qrCode.ErrorCorrectionLevel);
Assert.Equal(37, qrCode.Size);
Assert.Equal(1, qrCode.Mask);
Assert.Equal(Modules6, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules7 = {
"XXXXXXX XXXX X X X X XXXXXXX",
"X X X XXX XXXX X X",
"X XXX X X XX XX XXXXX X XXX X",
"X XXX X X X X X X X XXX X",
"X XXX X X XX XX XXX X XXX X",
"X X XX XX X X XX X X",
"XXXXXXX X X X X X X X X X XXXXXXX",
" X XXX XX XX XX ",
" XXXXXXX X X XX XX XX X",
" XXXX X X XXXXXX X XX X ",
"X XX X XX X X X X X XXX X",
"X XX X X XXXX XXXXXX X XX ",
" XXXX XX X XX XXX XXX XXXXX",
"XXX X X X XX XXX X X XX X ",
"XX XXXXX X X XXX X X X XXXX X",
"XX X XXXXX X X X X X X XXX",
" X X X XX X XXX ",
"XX XX X XXX XX X X XX X X XXX",
" XX XXX X XX XX X X X XX XX X",
"X X X X XXX XX X XX X XX",
" X XX X X X XX X X X XX XX",
"XX X XX XXXXXX XXXXXXX X X X",
"X X XXXXXX X XXX X X XX X XXX",
"X XXXX XX XXX XXX XX X XXX X XX",
"X XXX XXXX X XXXX XXXXXX X ",
" XXX X XXX X X X X",
"XXXXXXX XXX X X X X X X XX XX",
"X X X X X XX X X X X ",
"X XXX X XX X X X XXXXXXXXX XXX",
"X XXX X XX X XXXXX X X XX X X",
"X XXX X X XX X X XX X XXX ",
"X X X X X XX X X XX ",
"XXXXXXX XX XXX X XX XXX X X "
};
private const string Text7 = "こんにちwa、世界 αβγδ";
[Fact]
private void TestCode7()
{
var qrCode = EncodeText(Text7, Ecc.Quartile);
Assert.Same(Ecc.Quartile, qrCode.ErrorCorrectionLevel);
Assert.Equal(33, qrCode.Size);
Assert.Equal(2, qrCode.Mask);
Assert.Equal(Modules7, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules8 = {
"XXXXXXX X X XX X XXX X XX X X X X X XXXX X X XX X XX XXXXXX XX X XXX X XX X XX XXX XX X XX XXXXXXX",
"X X X XXX X XX X X XXXX X XXXX XX XX X X X XXXX XX XX XX X XXXX XX XXXXXX XX X X X",
"X XXX X XXX X X XX X X XXXXX X XXXXX X XX X X X XXXX XX XXX X XX X X X X XX X XX X XXX X",
"X XXX X XX XX X XXX X X XXX X XXX X X X X XXXXXXX XXXXXXXX XX X X XXXXX XX XXX XXXX X XXX X",
"X XXX X X XXX XXXX XXX XXXXX XXX X X XXXX X XX X XXXXXXXX X XX X XXXX XXXXXXX XX X XX XX X X XXX X",
"X X XX XX XX X XXXX X X XX X X X X XX XX X XXX XX XXX X X X XX X XXX XX XXX X X",
"XXXXXXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X XXXXXXX",
" X XXX X X X X X XX X XXX X XXX XX X X XX X X X XXX X X XXXX X X XXXXXXXX ",
" XXX X X XX X XX XX X X XXXXXX X X XXX X X XXXXX X XX X X X X XXXXXXXXX X XXX XX XXXX XXX XXX",
" XXXX XXX XXXXX XX X X X XX X X XX XXX XXXXXX XX XX X X XXX XXXX XXXXX X XXX X XX X X XX ",
"XX X XXX X X XX XXX X XX XXX X XXX XX X X X X XX XX X XXXX X XXXX X X XXXX X X XX XX",
" X XXX XXXXX X X XXX X XX X XX XXXX XX XX XX XX XXX X X XXX XX XX XXX X XX XXX X XXX X X X XXXX XXXXXXX X",
"X XXXXXX X XXX XX X XX XXXXXXX XXXXXXX XXXXX X X X X XX XX X XXXX XX X X X X XX X XX X X XXX XXXX ",
"XX XXX XX XXXX X XXXXX XX XXX XXX XX XX X X XX XX XXXX XX XXXX XX XXX XX X XX X XX XX X XX XX XX X ",
"XX XXXX X X XX XXXXX XXX X XXX XXXXX X XXX XXXXX X XXXXXX X XX X X XXX XXXX X X X XX X X X XX",
"X XX XXX X XX XX X XXXXXXX X XX X XX X XXXX XX X X XX XXXXX XX XX XX XXXXXX X XX X XXXXXXX XX",
"X X XX X XXX X XXXXXX X X XXXX X XXX XX X XX X XXX X XX X X XX XXX XXX X XXX X XX X XX X XXXX",
" X XX XXX XXXXXXXXXX X X XXXX XXXXX XXX XX X XX XX X XXX X X X XXXXXX XXX XX X XXXXX X X XXX X ",
"XX XXXX X XXXX X XXX XX X X X XX XXXX XXXX XXX XXX X X XXXX XXX XX XXXX X X XXXX X XXX X X XX",
" X XXX X XXXXX XXXX XX X XXXXX X XX XXXXX X XXXX XX XX XX XX X XXX XXXX X X XXXXXXXX X ",
" XX XX XXXX XXX XX X X X X X X X XX XX X X X XXXX XXXXX X X XX XXX X XX X XX XXXX X X X XX X",
"X X XX X XX X XX X X X XXXXX XXX X X XX XX X XX X XX X XXX X X X X XXX XXX X XXX X X X X X ",
" X X X XX X X XX XX X X X X X X XX X X XXXX X XX XX X X X X X XXXX XX X XXXX X X X XX XXXX",
"X X XX XX XXX XXXXXX XXXXX XXXXXXX X X X XX X XXXXX X X XXXX X X XXXX X X X XX X X XXX XX XX",
"X XX XXXXX XX XX XX XXXX XXXXX XXX XXX XX XX X X XX X XX XX X XX X XXX X XX XX X X XXXXX ",
"XX X X XX X X XX X X XXX X XX X XX XXXX XX XX X X X X XX X XXXX XX XX X XXX XX XX X XX X X ",
" X XXXX XXXXX XX XX X XXXX XXX XX XXX X X X X XXX X XXXXX XXX X XX XX XXXX X X XXXXXX X X XX",
" XX XX XXXXXXX X XX X XXXXX XX X X X XXXXXX XX X XXX XX XXXX X XXXXX X XXXX X XXX ",
" X XXXXX X XXXX X X X XXXXX XX XXX X X XXX X XXXXXXXXX XX X X XX X XXXX XXXXX X X X X X XXX XXXXX XXX",
" XX X X XXXXX X XXX XX X X XXX XX XX X X X X XXXXX XXX XX XX XX X XX XXXX X X XX XX ",
" X XX X X X X XX XXXX X X X X XXXX X X X X X X X X XXXX XX X XXX XX XX XX X XXXXX X X XXX XX X X X X X X X",
"XXX X X XX XX X X XX X X X X XX X X X X XXX X XXXXX XXXXX XX X X X XXXX X X XXXXXXXX X X",
" X XXXXXXX XXX XX XX X XXXXXXXXX XX XX X X XXX XXXXXXX XXX X X XXX X X X XXXXX X X XXX XX X XX XXXXXXXXX ",
"X XX X XXXXXXX XX X XXXXX X X X XXXX X X X XXXX XXXXX XX X X XXXXXX X XXXX X XXXXXX X X XXX X XX ",
"X XX XX X X XXX XX XX XXXX XX XX X XXX X XX X X XX XX X X X XX XX XX XX X X XXXX XXX XX XX",
" XXXX XXXXX XXXXXXXXX X X X XXXX X X XX XX XXXXX X X X XXX X XXX XXXXXX X XXX XXXX X ",
"XX X XXXX X XXXX XX XXX X XX XXXXX X X XXX X X X X X X XX XXXX XX X XXXXXX X X X X X XX X XX ",
"X XXXX X X X XXX X X X X XX XXXXXX X X X XX X X X XXXXX X X X XX X XXXXXX X X X X XXX XXX ",
"XXX X XX XX X X XX XXXXXXX X X XXXXX X XXXXX X X X X XXXX X XX X X XX X XXXX X X X X XX XX",
"XX X XXXX X X XX XX X XXX XX X XX XXXXX X X X X XXXX XXXX XXX XXX X X X XXXX XX XXXX XXX XX X ",
"X X XX X XXX X XX X X XXX XXXXXXX X XXXXXX XX XX XX XX X X XXXXX X X X XX X XX X X X XXXXX X X",
"XX XXX XX X X X X X XX X X XX XXXX X XXX XXXXXXX XX XX XXXX XX X XXXXXX X XX XXX X X X XX X X ",
"XX X XXX X X X X XXXXX X XX XX X X XX X X XX XX XX X X X X XX X XX X X XXX X X X X X",
" X XXX XX X X X X X X X X X XX X X X X XXXXXX XX XX XXXXX X XXX X XX X XXXX X XX X XXX X ",
"XX XXXXXXX X XXX X X X X XX XX XX XXXXX XXX XXX XX X XX XX X X XX X XXXX XXX XX X X X X XXXXX XXXX",
"X X X XXX X XX XX X X XXXX X X X X XXX X XXXXX X XXX X X X XX X X X X XXX X X X XXX XX XX ",
" X X X XX XX XXXX XXXXXXX XXXX XX X XX X XXX X XXX X XXXX X X XXXXXX XXXXX X X X XXXX XX X X XXX X",
" XX X XX X X X X XXXX XXXX XXX XX XXXX XXX XXX XX X X XX XXX XX X XX X XXX XX X XXXX XX XXX ",
"X X XXXXX XX XX XX X XX XXXXX X X XX X XXXX XX XXXXX X X X XXX XX X X X XX X XXXX XXX X",
"X XXXX X X XXXXX X X XX XXXX X XXXX X X XXXXXX XX XX XX XX X X X XX XXXX X X XX X XX X X ",
" XX X X XXX XX XXXX X X XXX XX X XXX X X XXX XXXX X XXXX XXX X X X X XX XXX X X XXXXX",
"XXXX XX XX XXX X X XX X XX XX XX X X XX XXXXX XX XX X X XXXXX XX X X XXX X X X X XXX XX X",
" X XX X XXX X XX XX XX XX XXXX XXXX XXXX XX X XXX XXXX XXX XXX X X X X X X XX X XXXXX XX XXX XXXX",
"XX XXX XX X X X XX X X X XX XXX X X X XXXX XX XX X X X XX XXXX X X XX ",
" X XXXXXX X X X XXX XX X XXX X XX XXX XXX X X X X XXX X X XX X X XXX X X X X X XX",
" XX XX XXX X XX XXX X X X XXXX X XXXX XX XXXX X X X XXXXXXX XXX XXXX XXX X XXX X XXXX X X XXXXXXXX XX X X",
"X XXXXXX XX X XXXXX X XXXXXXXX XX XXXX X XXXXXXX X XX X XXXXX X XXX X XX XX XXXXXXX ",
" X XX XXX XX X X X X XXX X X X XX XXXXXXX X X XX XXX XX XX X X X XX X XX X XX X X X X ",
" XX X X XXX X X X XXXXXXXX X X XX XXXXXXX XXXXX XX X XXXXXXX XX X X X X XX X XXX X XX X XX X X X XXXXX",
" XX X X X XX X X X XXX XX XX X X X X X X XXX XX XX XXX XXXX X XXXX X X XXXX XXX X X ",
" XXXXXXXX X XXXXXX XX XXXXXX XXX XX XX X XX XXXXXXXXX XX X XXXXXX X XXXXXXXXX XX XX XX XX XXXXXXX X",
"X X XXXXX XXXXXX XX XX X X XXXXXX X X XX XXXXX X XX XXX XXX XX X X X XX XXX XXX XX X X XX X XX X ",
" X X X XX X XXX X XXXXXX X X X XXXX XX X X XX XXX X X X X X XXX X XX X X X XXXX X X XX X XX",
"XXXXX XX XXX X X X X X X X X X X XX XXX XXXXXXXXX XXXX X X X XXX XXXX X X XXXX XX X XXXXX XXX X ",
"XX XX XX XX X X X XXX XXX X X X XX XX X X X X XXX X XXX XX X XXXXXX XXX X XXXX XXX ",
"XX X X XXX XXX XXXX X XXXXX XX X XXX XXXX XXXX XX X X X XX XXX X XXX X XXX XXX XX XX XXXXXX XX X ",
" X XXXXX XX XX X X XXXXXX XX XX XX XX X XX X X X X XX XX XX X XX X XX X X X XX X X X X X XX XX",
"XXX XX XX X XXX X XXX XXXX XX XXX XXX XXXX X X XXXXXX X X X XXXXX X XXXX X X XXXXX X XXXX XX X XX XX",
" XXX X XX XX X XXX X XXX XXXX XXX X XXX X X XXX X XX XXXX XXX XX XXXX XX XX XX X X XXX X XX X",
" X X XX X XXXX X X XX X X X X X X XXX XX X X X XXXXX X X XXX X X X XX XXXX X XXX XXX XXX ",
" XX X XXXX XXXXXXX X X X XX X XX XX X XXX X XXXXX XXX XXX XX XX XXX X XXXX X XXX X X X X XX",
" X XX X XXX X XXXX XX X X XXXX X XX X XXXXX X XXX XXX XX XXXXX X XXX X X X XXXX X X X X",
" X X XX X X XX X X X X XXX X X XX X X X XXXXXX X XXX XX XX XXXX XXXX X XX XXXX XXX X XXXX",
"XX X X XXX X X X XXX XX X X X XXXXXX X X X X X X XXXXX XX X X XX X X X X X X X XXXX XX ",
" X XX XX X X X X XXX XXXXX XXX X X XX X X X XXXXX X X X XXXXX X XXX X XXX XXXX X X XXX",
"X X XXX XX X XX XX X XXX X XXX X XXXXXX X XXXXXXX X XXXXX XX XX X X XXXX X XXXX XXX X X XX",
" XXXX X X X X XX XXX XXX X XX XXXX X X X X XXXX X X XX X X X XXXXX X XXX XXX",
" X X X XXXXXXX XX XXX XX XXX X XXXX XXX X X XXX X XXX XXX X X XXXX XX XXX X X X XX X XX XX X XXX X ",
" XXX X XX X XXX XX X X X X X XX XXXXXX XXXXXX X X XX X XX XXX X XX X X XXXX X X X X X X",
"XX XXX X X X X X X X X XXXX XXX X X X X X XX X XXXX X XX XX XX XXXX XX X X X XXXX XX XX X ",
"XXXXX X X XXX X XXX XXX X XX XXXXX X X X XXXXXX XXX XXX XXX XX XXX XXX XX XX X X X XX X X XX XX X X",
"XX X XX X XX X XXXXX X X XXXX XXXXX X XXXXXXXX X XXXXXXX XX XXXX XX XX XXXX X X X XXX XX X ",
" X XX XX X XXXXX X X XXX XXXX XXX XX XX X X X X XXXX XX X XX X X X X X X X X X",
" XX XX XX XXX XX X X X X XX XX XX XXX XXX X XXXX X X X XXX XXX XXX X XX XXXXXX XXX X X XXXX XX X X XX",
"X XXXXXXX X XXX X X XXXXX X X X XX X X X XXXXXXXXXXXX X X X X XXXX X XXXXXX X X X XX XX XXXXXXXXX",
"X XXX X X X XXXX XX XX XXX XX XX XXX XX X X X X X X XX XXXX X X X XX XX X X X XX X X XX ",
" XX X XX XXXXX X XXXX XX X X XX X X X X X X X X X X XXXXXXXXXXX XX X X X X X X XXXX X X X X XX X",
"X X X XX XX X XX X X X X X X XX XX XX XXX XX XXX XX XXX X XXXX X X XXXXXX X XX X XXX X X",
"X XXXXXXX XX XX X X X XXXXX XX XXX X X XXXX XXXXXXXXXXX X XXX XXXXX X XXXXXX X X X X XXX XX XXX XXXXX XXX",
" X XXX X X XX XXX X X XX XXX XX XX X X X XXX X XXX XXX XX XX X XX XX X XX XX ",
" XXX XXXXX XX X XXXX X XX X XX XX X X XXXX X X XXX X XXXX X XX XXX X X XXX X XXX X X X XX X XX",
"X X XXXXXX X XX XX XX X XX XXXXXXX X X X X X XX XX XXX XXXX XX XXXX X XXX X X XXXX X X XX X",
" X X XXX X XXX XXX XXXXXX X XX XXX XXX XXXXXX X XX X X XX XXX X XXX X XX XX X X XX X XX X XX X XXX X",
" X X XX XX X XX X X X XXXXXX X X X XX XXX XX XXXXX XX X XX X X XXX XX X X XXX X X XXX ",
"XXX XX X X XX X X X X XX XX XX XX XXX X XX X X XXXX X XX XXXXX X XX XXXXX X XXXXXX X XXXXX XX",
"XXX XX XX XXX X XX XX XX XX XXXX XXXXXXXXXX XX X X XX XX XX X XX X XX X X X XXXX XX X XX XXX XX X",
" X XXX X X X X X X X X X X X XX XXX XX X XXXX XX XXX X XX XXX X XXXXX X X XX XXX X ",
" X XXXX XXX X X XX X XXX X XX XXX XX XX XXXX X XX X XXX XX XXX X XXX XX XX X XX XXX X ",
"XXX XX XX XX XXXX X XX X XXX X X X X X XXXX XX XXXX X XX XXX XX X X X X X X XX X XX X X XXXX XX",
" X XXX XX XX X X XXXX X X XX X X XX X XXX X XXXX X XX X XX X XX X X X X X XXXXXX X XX ",
"XX XXXXXXX XX X XXXXXXX X XXXXX X XXX X X XX X XXX X XX XX XXX X X X X X XX X XXXX XXXX ",
"X X XX XXXXX X XX X X XXXXXXXX XXXXX X XX X XXX XXXXXXX X X X XXX X X X X XX X XX ",
"XXX X X X X XX X XXX XXX X X XX X XXX X X X XX X XX XX X XXX XXX XXX X XXXXXX X X XX X X",
" XXX XX XXXX X XX XXX X X XXX X X XX X XXXXXXX XX X XX X X X X XXXXX X X XXX XX X XXXXXX X X ",
"XX XXXXX XX XX X X XX X X X X XX XX XX X XXX X XX XX X X X XXX XXXXX XXXXX X XXX XXXX X XX X XXX X",
" X X XX X X XXXX XX XXXX X XX X XX X X X XX X XX XXX X X X X XX XXXXX X XX XXXX X X X XX ",
"XXX XX X XX XXX X XX X X XX X X X XXX XX XXXXX XX XX X X XXX X XX XX XX X X XXXXXX XXXXXX XX",
"X XXXX XXXXXX XX X XX X X X X X X XXXXXXXX X XXXX XXX X X XXXX XX XXX X XX X X X XXXX XX X XX X X XX X X XX",
"X X X X XXX X XX XX X X XX XXX XX X XXX XX XXX XX XXXXX X X XX XX XXXX X X X XX X XXX ",
"X X X X X X X XXX X X XXXX X X X X XX X XX XXXX XXXXXXXXX X XXX X X X X X X XXX XX ",
"XX X XXXXXX XXX X X XX XXXXXXX X XX XX X XXX X XX X XXXX XXX XX X X X X X XXXX X X X XXX XXX",
"X XXXX XX XX X XX XX X XXXX X XX X XX X X XX XXX XX XX XX X X XX X XX X X XXX X ",
" XXX X X X X XXX XXXXXX X X XXXXX XXXX XXXXXXXX XX XX X XX X XXXXXX X XX X XX X XXX XX XXXXXX X X",
" X XXXX XXXXXXXX XXXX XXXXXXXXXXX XXX X XX X XXX X XXX XX XX XXX X XX X X X XX XXX XX XX XXX ",
"XXXXXXX XX XX XXX X X X X XX XX XX X X XXX XX X X X X XX XXXXX X X X XXXXX X XXXXXXX X X X XX XX",
"X X X X X X XXX XX X X X X X XXX XX X X X X X XX X XX X XX X XXXX XX X XX XXX X X XX",
"X XXX X XX X X XX X X X XXXXXX X XX X XX XX XXXXXXXX X X X XXXXXXXX XX X X XXXXXXX ",
"X XXX X XX X XX XX XX X X XXX X XX X XXX XX X X XX XX XX XXXX XX X X XX XX XX X XX X XX XX XX X X",
"X XXX X XXXXXXX XXXXXX X XXX X X X XXX XXXXX X XXXXXX X XXXXXX X X XX X X XXXX X XXX X X XX X X",
"X X XX X XXX X X XX X X XXX XXX X X XXX XXXXXX X X X X X XX X X XX XXXXXXX XXXX X X XXXXXX XX X",
"XXXXXXX X X X X X X XX XXXX X X X XX X X X X XXXXX X X X X X X XX XX XXX XXXXX XXXX"
};
private const string Text8 = "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice 'without pictures or conversations?' So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.";
[Fact]
private void TestCode8()
{
var qrCode = EncodeText(Text8, Ecc.High);
Assert.Same(Ecc.High, qrCode.ErrorCorrectionLevel);
Assert.Equal(121, qrCode.Size);
Assert.Equal(2, qrCode.Mask);
Assert.Equal(Modules8, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules9 = {
"XXXXXXX XXXXXX XXX XXXXXXX",
"X X XXXX X XXXXX X X",
"X XXX X X X X X X X XXX X",
"X XXX X X XXX X XX XX X XXX X",
"X XXX X XX X XXX X XXX X",
"X X X X XXX X X X X",
"XXXXXXX X X X X X X X XXXXXXX",
" X XX X XXX ",
" X XXXXX XX XXXXXXXX XXXXX ",
" X XX XX X XXX XX X XX",
" X XXX XX X XX X XX X X X X",
" X XX XXX X X XX X XX ",
" X XX X X X XXXXX XX X ",
"X XXX XXX X X XX X X X",
"XXXXX X X XX X XX XX X",
"XX XXX X X X X XXX XX X X X",
" XX X X X XX X X XX XX ",
" XX X X X XX X X XX X X",
"XX XXX X X X XX X X",
" X XXX XXX XXXX XX X",
"XXXX XX X X X XXXXX X",
" X XXX X XXX XX X",
"XXXXXXX XXX X XX X X XXX X",
"X X X X X X XX XX X",
"X XXX X XX XXXXXXX ",
"X XXX X X X X XX XXX X ",
"X XXX X XX X XX XX X X XXX",
"X X XX X X X X X ",
"XXXXXXX XXXXXXX X XXXX X"
};
private const string Text9 = "https://www.nayuki.io/";
[Fact]
private void TestCode9()
{
var segments = QrSegment.MakeSegments(Text9);
var qrCode = EncodeSegments(segments, Ecc.High, 1, 40, -1, true);
Assert.Same(Ecc.High, qrCode.ErrorCorrectionLevel);
Assert.Equal(29, qrCode.Size);
Assert.Equal(1, qrCode.Mask);
Assert.Equal(Modules9, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules10 = {
"XXXXXXX X XX X X XXXXXXX",
"X X XX XXXX XXX X X",
"X XXX X X XXX X X X XXX X",
"X XXX X XXX XXXXXXX X XXX X",
"X XXX X X X X X X X X XXX X",
"X X X X XX X X",
"XXXXXXX X X X X X X X XXXXXXX",
" XX X XXX ",
" XX XXX X X XX X ",
"XX X X XXXX X XX X X",
"XXXX XXXX XXX XX X XXX ",
" X XXX X X X",
" X X XX XXX X XXXX X XXXX",
"X XXX X X X XX X XX XX X",
" X XXX XX X X X XXX XXX XX",
" X XX X XXX XXXXXXX XX XX",
"X XX XXXX XXXXX X XX XXX XX",
" X X XXX X XX X XX ",
"X X XX XXXX XXX X XX X ",
" X XXX X X X X XXXXXX X",
" X XXXX X XX X XXXXX XXX",
" XX X X XX XX XX",
"XXXXXXX X XXXXXX XX X X XX ",
"X X X XXX X X ",
"X XXX X XX XXX XXXXXXX X",
"X XXX X XX X X XXXX ",
"X XXX X X XX XX X X X X",
"X X X X XX XXX XX X ",
"XXXXXXX X X X XXXX X X "
};
private const string Text10 = "https://www.nayuki.io/";
[Fact]
private void TestCode10()
{
var segments = QrSegment.MakeSegments(Text10);
var qrCode = EncodeSegments(segments, Ecc.High, 1, 40, 3, true);
Assert.Same(Ecc.High, qrCode.ErrorCorrectionLevel);
Assert.Equal(29, qrCode.Size);
Assert.Equal(3, qrCode.Mask);
Assert.Equal(Modules10, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules11 = {
"XXXXXXX X XX X XX XXX X XXX X XXXXXXX",
"X X X XXX XX XXXX XX X X XX X XXX X X",
"X XXX X X X XX X XXXX XXXXXXXX X XX X XXX X",
"X XXX X X XXX XXXX XX X XXX XX XXXX X X XXX X",
"X XXX X X XXX XX XXXXXXX XX XXXX X X XXX X",
"X X XXXXX X XX XXXXXXXXX XX X X",
"XXXXXXX X X X X X X X X X X X X X X X X X XXXXXXX",
" XXXXX XX X XXX XXXXX XX ",
"X X X X XX XX XXXXXX X XXX XX X X ",
" XXX X XX XX XXX X XXX XX XXXX XXXXX X XX",
"XXXX XX X XX X X X X X XXX XXX XXX XXX ",
" X XX X XX XX XXX XXXX XX XXXX X XXX X ",
"X XXX X X X XXXX XXX XXX XXX X ",
" XX XX X X XX XXX X XX XXX X X X X",
" X X XX X XX XX X XX XX XX XX ",
"X X XXXXXX XX X XX XX XXXX X XX XX X X X",
"XXXXXXXXXXXXXX X XX X X X X X X XX",
"X X X X XXXX XXXXX XX XXX XX X X X XX",
"XXX X XXXXX X X XX XX X XX X XXX ",
" X X X XXX X XXX X XXXXX XXX X X X XXX X",
"XX XX X X XX XX X X XX",
" X XXX X XX X XX XXXX XX X XXX XXX XXXXX",
" X XXXXXX XX XX XXXXXXXXX XX XXXX XXXXX ",
"XXXXX X X XX XX X XX XX XXX XXXXXX X X ",
"XXX X X X XX XXXX XXX X X X XX XX XX X X XX",
" XXX X XXX X XXX X XX XXX X XX X X X ",
"XXX XXXXX XX XX XXX XXXXXX X XX XXXXXXXX ",
"X X X X XX XXX XXX X XXXXX XXX X XXX X",
" XXXX XX X XX X XXXX X X XXXX X XXX XX XX",
" X XXXX XXXX X X X XXX XXX XXXX X X XX",
"X XXX X X XXX XXXX XX X X XX X XX X X X ",
" XXXXX XX XX XXXX X XX X XX XX X XXXX ",
" XXXX XXXX X X X X X X XX X XX X XX XXX ",
"XX X X X X X XXXXXXX XXXX XXX XXXX X X X X",
" X XXX X XX X XXX X X XXX X XX XXXX ",
" X XX XX XX XX XXXX XXX XXXXXXX X XX XX ",
" X X X X XX XX X X X XXX X X XX X X ",
" X X X X XXX XXXX XX XX X X X XX XXXXXX ",
" X XXXXXX X X XXXX X X XXX ",
" XXX X XX X X XXXX X X X XXXX X X X ",
"XXX XXX X X XXX XXXXXXX X X XX XXXXXXX XX",
" X X X XX X X XX X X XX X X X X",
"XXXXXXX X XX XXXXXX XX X XXX X XX X X X XX",
"X X XX X XX X X X X X X X XX XXXX ",
"X XXX X XX X X XX X XXXXX XXX X XXXXXXX X ",
"X XXX X X XX XX X X XXX XXX XX XXXXXX XXX ",
"X XXX X XXX XX XX XXX XXX XX X XX XX XX ",
"X X XXXXX XX XX XXX XX X XXX X XXX ",
"XXXXXXX X X X X X XXXX XX XX X X XXX XX"
};
private const string Text11 = "維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫";
[Fact]
private void TestCode11()
{
var segments = QrSegment.MakeSegments(Text11);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 0, true);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(49, qrCode.Size);
Assert.Equal(0, qrCode.Mask);
Assert.Equal(Modules11, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules12 = {
"XXXXXXX XX XX X XXX XXX XX XXX X X XXXXXXX",
"X X XX XXX X XXX X XX XXXXXX X X",
"X XXX X XX XX X XX X X X XX XX X XXX X",
"X XXX X X X XX XX X XXX X X X XXX X",
"X XXX X X X XX XX XXXXXX XXX X X XXX X",
"X X XXX X XXXX X X X X X X XX X X X",
"XXXXXXX X X X X X X X X X X X X X X X X X XXXXXXX",
" X XX X XXX XX X XX X X XX ",
"X X XX XX XX X X XXXXXX X X XX X X X",
" X X XXX XX XXXX X X XX X XXX X XXXX X",
"X X XXXX XX X XXXXXX XX X XX XX X X ",
" XX XX XX X X XX XX X XX XXX X XXX ",
"XX X X X X XX X X XX XXX XXXX X X X X ",
" X XX X XXXX X X XXXX X XXX XX XX XXXXXXXXX",
" XXXXXX XX XX X X XXXX X XX X X XX XX X ",
"XX X X XX X X XXXXX XX X XX XX XXXXXXX",
"X X X X X X X XXXX XXX X XXX XXX XXX X X X",
"XXXXXX XXXX X XX X XXX XX XXX XXX XXX XXX X X",
"X XXXXX X XXXXXXX X XX X X X X XX XXXX XX X ",
" X X XX XX X XX X XXX XXXX XX XXX",
"X XXXX X X X X X X X X X XX XX X XXX X X",
" X XXX XX XXX X XX X X XX XXX XXX X X",
" XXXXXXXX XX XXX X XXXXXX X XX X XXXXXXXX X ",
"X X X XXXX XXX X X X X X XXX XX X ",
"X XXX X XXX X XX XX X X XX XXX XXX X X XX X",
" XX X XX XX XXXXX XXX X X X XXX XX ",
"X XXXXXXXX XXX X XXXXXX X X X XXXXXXX X ",
"XX X X XX XX XX X X X X X XX XXX",
" X XXX XXXX X X XXXXXX X XXXX X XX X X",
" X XXX X XX X XX X XXX X X X XXXXXX X",
"XXX XXXXXXX XXX X XXXX X X XX XXXX X ",
" X X XX XX XX X XX X XX XX X XX X ",
" X X XX X XXXXXX XXXXXXXX XX X XX X ",
"X X XXX X X X X XX X X X XXXXXXXXX",
" X XX XXXXX X XXXXX X X X XX X X XX ",
" XXXX XX XX X XX XX X X X X X XXX XXX ",
" XXXXXXX XXX X XXX X X XXXX X X ",
" XXXXX X XXXX XX X XXX XXXXXX XXXX XX X X ",
" X XX X XXXX X XXXX X X X X X X X X X X ",
" XXX XX X X X X XXXXXXXXX X X XXX ",
"XXX X XXXXXX X XX XXXXXX X XXX XXXXXX X",
" XXXX X XXXXX X XXXXXX X XX XXXXX",
"XXXXXXX X XXX X X X X X XX X XX XX X XX X",
"X X XX XX XXXX XXXX XXXXXXX X X X ",
"X XXX X XX XXXXXXXXX XX XXXX X XXXXX ",
"X XXX X XXX XXX X XX XX XXX X X X X ",
"X XXX X X XXX XX X X X XX X XX XX XX ",
"X X XX X XX XXX X XX X XXXX XX XXX X ",
"XXXXXXX XXXX XXX X X XX XX XX XXX X X"
};
private const string Text12 = "維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫";
[Fact]
private void TestCode12()
{
var segments = QrSegment.MakeSegments(Text12);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 1, true);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(49, qrCode.Size);
Assert.Equal(1, qrCode.Mask);
Assert.Equal(Modules12, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules13 = {
"XXXXXXX X XX X XXX XXX XX XXX X X XXXXXXX",
"X X XXX XX XXX XX X XX X XXXX X X",
"X XXX X XXXX XXX X XX XX X XXX X XX X XXX X",
"X XXX X X X X XXX X X X X X X XXX X",
"X XXX X XXXXXX XXXXXXXXX X X X XXX X",
"X X XX XXXXXX X X X X XXX X X X",
"XXXXXXX X X X X X X X X X X X X X X X X X XXXXXXX",
" XX X X XX XX X XXX X X X XX ",
"X X XX X X XXXXXXX X XX X X XXXX XXX ",
"XXX X X XX X XXXX X XX X X XX ",
"XX XXX XXXX X XX X X X X XX X X X X ",
"X XX XXXXX X X XXX X XXXXXX XXXX",
"XX X X X X XX X X XX XXX XXXX X X X X ",
"XX XX X XX X X XXXXXX X X X X XX XXX XX XXXXX ",
" X XXX XXX X XXX X X X XX X X ",
" XXXX XXX X X X XX X XX X XX X X X ",
"XX XXX XXXXX XXXX X X X XX XXX XXXXX",
" XXXXX XXXX XX XXX XXX XX XXXXXXX X X X ",
"X XXXXX X XXXXXXX X XX X X X X XX XXXX XX X ",
"X X XX XX X X XXX X XX XX X XXX XX ",
"XXX X XXX XXXX XXX XXXXX X XXXX X XXXXX",
"X X X XX XX X X XX XXX XXXX X X ",
" XXXXXX XXX X XX XXXXXXX X XXXXX XXXXXXXX ",
" X X XXXXX XXX X X X X XXX XX XX",
"X XXX X XXX X XX XX X X XX XXX XXX X X XX X",
"XXX X XX X XXXX XXX X XX XXX XX X",
"XX XXXXXXXXXX XXXXX XXXXXXX XXXX X XXXXXX X ",
" XX X XX XXXX XX XX X XXX X X XX X ",
" X XXXX XXXXXX X X XXXXX X X XXX XXXXX",
"XX XXX X XXX X XXX X X X X X X XX XXX ",
"XXX XXXXXXX XXX X XXXX X X XX XXXX X ",
"X X X XX X XX X XX XX X XXXX X X",
" X XX X XX X XXX X X X XXX X X XXX X X ",
" X X XXX XX XXX X XX X X X X X X ",
" XXXX XX X XXX XXXXXX X XXXXXXX X X XX X ",
"XXXXX XX X X X XX X X X X XXXX XXX X",
" XXXXXXX XXX X XXX X X XXXX X X ",
"XXXXXX X X XX XXX X XX XX XXX X XX X X X X",
" X XXX X XXX X X XXX XXXX X X X X ",
" XXX X XXXX XXXXX X X X X X XXX X XX XX",
"XXX XX X X X X XXXXXXXX X XXX XXXXXXXXX",
" XXXXX X XXXX X X XXXX XX XX XXXX ",
"XXXXXXX XXX X X X X X XX X XX XX X XX X",
"X X XXX XXXXXXX XXXXXXXXXX X X X X X",
"X XXX X XX XX XXXXXXXX XX X X XXXXX XX ",
"X XXX X X X X XX XX XX XX X XXX X",
"X XXX X XXX X X X XXX XXXX XXX X ",
"X X XX XX XX XXXX XXX XX X X X X",
"XXXXXXX XXXX XXX X X XX XX XX XXX X X"
};
private const string Text13 = "維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫";
[Fact]
private void TestCode13()
{
var segments = QrSegment.MakeSegments(Text13);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 5, true);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(49, qrCode.Size);
Assert.Equal(5, qrCode.Mask);
Assert.Equal(Modules13, TestHelper.ToStringArray(qrCode));
}
private static readonly string[] Modules14 = {
"XXXXXXX X XX X XX XXX X XXX X XXXXXXX",
"X X XXXXXXXX X X X XXX X X XXXXX X X",
"X XXX X XX X XXXX X XXX XX XXX X XX X XXX X",
"X XXX X X XXX XXXX XX X XXX XX XXXX X X XXX X",
"X XXX X XXX X XXXXXXXX XXXXXX X X XXX X",
"X X X X XX XX XXX XXX XX XXX XX X X",
"XXXXXXX X X X X X X X X X X X X X X X X X XXXXXXX",
" X X XX X X XX XX X X X ",
"X X XX X X X X X XXXXXX X XXXX X X X ",
" XXX X XX XX XXX X XXX XX XXXX XXXXX X XX",
"X XXXXXXX XXXX XXX X XX XXX XXX X X XXX XXX ",
" XXXXX XXXXX X XXXXX X XXXX X XXX XXX XX ",
"X XXX X X X XXXX XXX XXX XXX X ",
" X X X X XX X XX X XXX XX X XXX XXX X",
" XXXXXX X XXXX X XX X X X X XXXX X X ",
"X X XXXXXX XX X XX XX XXXX X XX XX X X X",
"X XX XX XX XX X X XX XX XX XX X XXX",
"X XX X XXX X XX X XXXXXX XX XX X X",
"XXX X XXXXX X X XX XX X XX X XXX ",
" XXX XXX XXX XX XXX XXXXX XX XXX XXX X",
"XXXXXXX X X XX X X X X X XXXX XX XX X X",
" X XXX X XX X XX XXXX XX X XXX XXX XXXXX",
" XX XXXXXXXXXX X X XXXXXXX X X XXX X XXXXX X ",
"XX XX X XX X X XXXX XX XXXXX XX X X X ",
"XXX X X X XX XXXX XXX X X X XX XX XX X X XX",
" XXXX X X X X X X X XXXXX XX X X X XX ",
"XX XXXXX X X XXXXXXXXX X XX X X XXXXXXX ",
"X X X X XX XXX XXX X XXXXX XXX X XXX X",
" XX X X XX XX XXX XXX X XXXXXX XXX",
" X XX X XXX X XXX XX XX XX XXXXX X XXXX X",
"X XXX X X XXX XXXX XX X X XX X XX X X X ",
" XX X XXXX X XX XX X XX X XXXX XX XXX X ",
" XXX X XXX X XX XX XXX X XX X XX X XXX ",
"XX X X X X X XXXXXXX XXXX XXX XXXX X X X X",
" X X X X XXXX XX XXX XX X X XX ",
" X X X X X X X XXXXX X XX XXX XX X X ",
" X X X X XX XX X X X XXX X X XX X X ",
" XX X XXXX XX X X XXX X XXXXX X XX X ",
" X XXX XXXX X XX XX X X XX X XX X X X X ",
" XXX X XX X X XXXX X X X XXXX X X X ",
"XXX X X XX X X XXXXXXXX XX X XXXXXXXXXXXX XXX",
" X XX XX X X XX XX X X X X XXX",
"XXXXXXX X XX XXXXXX XX X XXX X XX X X X XX",
"X X XX X XX X X XX XX XX XX X ",
"X XXX X X XXXXX XXXXX XXX XX XXXXXXXX ",
"X XXX X XX XX XX X X XXX XXX XX XXXXXX XXX ",
"X XXX X X X X X X X XXXXXX XX XXXXXXX X ",
"X X X XX X X XXXXXX X XXXX XX XXX ",
"XXXXXXX X X X X X XXXX XX XX X X XXX XX"
};
private const string Text14 = "維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫";
[Fact]
private void TestCode14()
{
var segments = QrSegment.MakeSegments(Text14);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 7, true);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(49, qrCode.Size);
Assert.Equal(7, qrCode.Mask);
Assert.Equal(Modules14, TestHelper.ToStringArray(qrCode));
}
}
}

@ -0,0 +1,158 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Xunit;
namespace Io.Nayuki.QrCodeGen.Test
{
public class QrSegmentEncodingTest
{
private static readonly string TextNumeric = "83930";
private static readonly int BitLengthNumeric = 17;
private static readonly byte[] BitsNumeric = { 139, 243, 0 };
private static readonly string TextAlphanumeric = "$%*+-./ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static readonly int BitLengthAlphanumeric = 242;
private static readonly byte[] BitsAlphanumeric = {
43, 63,240, 245, 223, 12, 64, 232,
162, 147, 168, 116,228, 172, 40, 21,
170, 67, 243, 58, 211, 175, 81, 76,
109, 33, 107, 218, 193, 225, 2
};
private static readonly string TextUtf8 = "😐ö€";
private static readonly int BitLengthUtf8 = 72;
private static readonly byte[] BitsUtf8 = { 15, 249, 25, 9, 195, 109, 71, 65, 53 };
[Fact]
void NumericEncoding()
{
QrSegment segment = QrSegment.MakeNumeric(TextNumeric);
Assert.Equal(segment.EncodingMode, QrSegment.Mode.Numeric);
Assert.Equal(TextNumeric.Length, segment.NumChars);
BitArray data = segment.GetData();
Assert.Equal(BitLengthNumeric, data.Length);
Assert.Equal(BitsNumeric, BitArrayToByteArray(data));
}
[Fact]
void RejectNonNumeric()
{
Assert.Throws<ArgumentOutOfRangeException>(() => QrSegment.MakeNumeric("abc"));
}
[Fact]
void AlphanumericEncoding()
{
QrSegment segment = QrSegment.MakeAlphanumeric(TextAlphanumeric);
Assert.Equal(segment.EncodingMode, QrSegment.Mode.Alphanumeric);
Assert.Equal(TextAlphanumeric.Length, segment.NumChars);
BitArray data = segment.GetData();
Assert.Equal(BitLengthAlphanumeric, data.Length);
Assert.Equal(BitsAlphanumeric, BitArrayToByteArray(data));
}
[Fact]
void RejectNonAlphanumeric()
{
Assert.Throws<ArgumentOutOfRangeException>(() => QrSegment.MakeAlphanumeric("abc,def"));
}
[Fact]
void AutoNumericEncoding()
{
List<QrSegment> segments = QrSegment.MakeSegments(TextNumeric);
Assert.Single(segments);
QrSegment segment = segments[0];
Assert.Equal(segment.EncodingMode, QrSegment.Mode.Numeric);
Assert.Equal(TextNumeric.Length, segment.NumChars);
BitArray data = segment.GetData();
Assert.Equal(BitLengthNumeric, data.Length);
Assert.Equal(BitsNumeric, BitArrayToByteArray(data));
}
[Fact]
void AutoAlphanumericEncoding()
{
List<QrSegment> segments = QrSegment.MakeSegments(TextAlphanumeric);
Assert.Single(segments);
QrSegment segment = segments[0];
Assert.Equal(segment.EncodingMode, QrSegment.Mode.Alphanumeric);
Assert.Equal(TextAlphanumeric.Length, segment.NumChars);
BitArray data = segment.GetData();
Assert.Equal(BitLengthAlphanumeric, data.Length);
Assert.Equal(BitsAlphanumeric, BitArrayToByteArray(data));
}
[Fact]
void Utf8Encoding()
{
List<QrSegment> segments = QrSegment.MakeSegments(TextUtf8);
Assert.Single(segments);
QrSegment segment = segments[0];
Assert.Equal(segment.EncodingMode, QrSegment.Mode.Byte);
Assert.Equal(Encoding.UTF8.GetBytes(TextUtf8).Length, segment.NumChars);
BitArray data = segment.GetData();
Assert.Equal(BitLengthUtf8, data.Length);
Assert.Equal(BitsUtf8, BitArrayToByteArray(data));
}
[Fact]
void EmptyTest()
{
List<QrSegment> segments = QrSegment.MakeSegments("");
Assert.Empty(segments);
}
private static byte[] BitArrayToByteArray(BitArray buffer)
{
int len = buffer.Length;
byte[] result = new byte[(len + 7) / 8];
buffer.CopyTo(result, 0);
return result;
}
}
}

@ -0,0 +1,75 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
using Xunit;
namespace Io.Nayuki.QrCodeGen.Test
{
public class QrSegmentRegexTest
{
[Fact]
void IsNumeric()
{
Assert.Matches(QrSegment.NumericRegex, "1234");
}
[Fact]
void EmptyIsNumeric()
{
Assert.Matches(QrSegment.NumericRegex, "");
}
[Fact]
void TextIsNotNumeric()
{
Assert.DoesNotMatch(QrSegment.NumericRegex, "123a");
}
[Fact]
void WhitespaceIsNotNumeric()
{
Assert.DoesNotMatch(QrSegment.NumericRegex, "123\n345");
}
[Fact]
void ValidAlphanumeric()
{
Assert.Matches(QrSegment.AlphanumericRegex, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./");
}
[Fact]
void EmptyIsAlphanumeric()
{
Assert.Matches(QrSegment.AlphanumericRegex, "");
}
[Fact]
void InvalidAlphanumeric()
{
Assert.DoesNotMatch(QrSegment.AlphanumericRegex, ",");
Assert.DoesNotMatch(QrSegment.AlphanumericRegex, "^");
Assert.DoesNotMatch(QrSegment.AlphanumericRegex, "(");
Assert.DoesNotMatch(QrSegment.AlphanumericRegex, "a");
}
}
}

@ -0,0 +1,47 @@
/*
* QR Code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
namespace Io.Nayuki.QrCodeGen.Test
{
internal class TestHelper
{
internal static string[] ToStringArray(QrCode qrCode)
{
int size = qrCode.Size;
string[] result = new string[size];
for (int y = 0; y < size; y++)
{
char[] row = new char[size];
for (int x = 0; x < size; x++)
{
row[x] = qrCode.GetModule(x, y) ? 'X' : ' ';
}
result[y] = new string(row);
}
return result;
}
}
}
Loading…
Cancel
Save