diff --git a/.github/workflows/wf-build-release-ci.yml b/.github/workflows/wf-build-release-ci.yml index 1f096321..91b9bb5b 100644 --- a/.github/workflows/wf-build-release-ci.yml +++ b/.github/workflows/wf-build-release-ci.yml @@ -10,11 +10,11 @@ jobs: env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 name: Checkout Code - name: Install additional .NET SDKs - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 1.0.x @@ -26,7 +26,7 @@ jobs: uses: microsoft/setup-msbuild@v1 - name: Setup NuGet - uses: NuGet/setup-nuget@v1.0.2 + uses: NuGet/setup-nuget@v2 - name: Restore NuGet Packages run: nuget restore QRCoder.sln @@ -35,7 +35,7 @@ jobs: run: msbuild QRCoder.sln /p:Configuration=Release /p:NoWarn="1182" /p:NoWarn="1701" /nr:false /t:Rebuild - name: Upload artifacts - uses: actions/upload-artifact@v1.0.0 + uses: actions/upload-artifact@v4 with: name: Compiled project path: D:\a\qrcoder\qrcoder @@ -45,13 +45,13 @@ jobs: runs-on: windows-2019 steps: - name: Download artifacts - uses: actions/download-artifact@v1.0.0 + uses: actions/download-artifact@v4 with: name: Compiled project path: D:\a\qrcoder\qrcoder - name: Install additional .NET SDKs - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 1.0.x @@ -123,16 +123,16 @@ jobs: needs: test runs-on: windows-2019 env: - GH_PKG_SEC: ${{ secrets.GH_PKG_REPO }} + GH_PKG_SEC: ${{ secrets.GITHUB_TOKEN }} steps: - name: Download artifacts - uses: actions/download-artifact@v1.0.0 + uses: actions/download-artifact@v4 with: name: Compiled project path: D:\a\qrcoder\qrcoder - name: Install additional .NET SDKs - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 1.0.x @@ -177,6 +177,6 @@ jobs: runs-on: windows-2019 steps: - name: Delete artifacts - uses: GeekyEggo/delete-artifact@v1.0.0 + uses: GeekyEggo/delete-artifact@v5 with: name: Compiled project diff --git a/.github/workflows/wf-build-release.yml b/.github/workflows/wf-build-release.yml index 003541be..530b472f 100644 --- a/.github/workflows/wf-build-release.yml +++ b/.github/workflows/wf-build-release.yml @@ -11,11 +11,11 @@ jobs: env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 name: Checkout Code - name: Install additional .NET SDKs - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 1.0.x @@ -27,7 +27,7 @@ jobs: uses: microsoft/setup-msbuild@v1 - name: Setup NuGet - uses: NuGet/setup-nuget@v1.0.2 + uses: NuGet/setup-nuget@v2 - name: Restore NuGet Packages run: nuget restore QRCoder.sln @@ -36,7 +36,7 @@ jobs: run: msbuild QRCoder.sln /p:Configuration=Release /p:NoWarn="1182" /p:NoWarn="1701" /nr:false /t:Rebuild - name: Upload artifacts - uses: actions/upload-artifact@v1.0.0 + uses: actions/upload-artifact@v4 with: name: Compiled project path: D:\a\qrcoder\qrcoder @@ -46,7 +46,7 @@ jobs: runs-on: windows-2019 steps: - name: Download artifacts - uses: actions/download-artifact@v1.0.0 + uses: actions/download-artifact@v4 with: name: Compiled project path: D:\a\qrcoder\qrcoder @@ -123,16 +123,16 @@ jobs: needs: test runs-on: windows-2019 env: - GH_PKG_SEC: ${{ secrets.GH_PKG_REPO }} + GH_PKG_SEC: ${{ secrets.GITHUB_TOKEN }} steps: - name: Download artifacts - uses: actions/download-artifact@v1.0.0 + uses: actions/download-artifact@v4 with: name: Compiled project path: D:\a\qrcoder\qrcoder - name: Install additional .NET SDKs - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 1.0.x @@ -171,6 +171,6 @@ jobs: runs-on: windows-2019 steps: - name: Delete artifacts - uses: GeekyEggo/delete-artifact@v1.0.0 + uses: GeekyEggo/delete-artifact@v5 with: name: Compiled project diff --git a/.github/workflows/wf-build-test.yml b/.github/workflows/wf-build-test.yml index d6d016ec..7947f200 100644 --- a/.github/workflows/wf-build-test.yml +++ b/.github/workflows/wf-build-test.yml @@ -10,11 +10,11 @@ jobs: env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 name: Checkout Code - name: Install additional .NET SDKs - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 1.0.x @@ -26,7 +26,7 @@ jobs: uses: microsoft/setup-msbuild@v1 - name: Setup NuGet - uses: NuGet/setup-nuget@v1.0.2 + uses: NuGet/setup-nuget@v2 - name: Restore NuGet Packages run: nuget restore QRCoder.sln @@ -35,7 +35,7 @@ jobs: run: msbuild QRCoder.sln /p:Configuration=Release /p:NoWarn="1182" /p:NoWarn="1701" /nr:false /t:Rebuild - name: Upload artifacts - uses: actions/upload-artifact@v1.0.0 + uses: actions/upload-artifact@v4 with: name: Compiled project path: D:\a\qrcoder\qrcoder @@ -45,13 +45,13 @@ jobs: runs-on: windows-2019 steps: - name: Download artifacts - uses: actions/download-artifact@v1.0.0 + uses: actions/download-artifact@v4 with: name: Compiled project path: D:\a\qrcoder\qrcoder - name: Install additional .NET SDKs - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 1.0.x @@ -89,6 +89,6 @@ jobs: runs-on: windows-2019 steps: - name: Delete artifacts - uses: GeekyEggo/delete-artifact@v1.0.0 + uses: GeekyEggo/delete-artifact@v5 with: name: Compiled project diff --git a/QRCoder/ASCIIQRCode.cs b/QRCoder/ASCIIQRCode.cs index bffe7cd0..f18d7266 100644 --- a/QRCoder/ASCIIQRCode.cs +++ b/QRCoder/ASCIIQRCode.cs @@ -52,7 +52,7 @@ public string[] GetLineByLineGraphic(int repeatPerModule, string darkColorString var lineBuilder = new StringBuilder(); for (var x = 0; x < QrCodeData.ModuleMatrix.Count - quietZonesModifier; x++) { - var module = QrCodeData.ModuleMatrix[x + quietZonesOffset][((y + verticalNumberOfRepeats) / verticalNumberOfRepeats - 1)+quietZonesOffset]; + var module = QrCodeData.ModuleMatrix[((y + verticalNumberOfRepeats) / verticalNumberOfRepeats - 1)+quietZonesOffset][x + quietZonesOffset]; for (var i = 0; i < repeatPerModule; i++) { lineBuilder.Append(module ? darkColorString : whiteSpaceString); @@ -75,4 +75,4 @@ public static string GetQRCode(string plainText, int pixelsPerModule, string dar return qrCode.GetGraphic(pixelsPerModule, darkColorString, whiteSpaceString, drawQuietZones, endOfLine); } } -} \ No newline at end of file +} diff --git a/QRCoder/PayloadGenerator.cs b/QRCoder/PayloadGenerator.cs index 6275e5be..7c7c83f8 100644 --- a/QRCoder/PayloadGenerator.cs +++ b/QRCoder/PayloadGenerator.cs @@ -53,7 +53,8 @@ public enum Authentication { WEP, WPA, - nopass + nopass, + WPA2 } } @@ -311,7 +312,7 @@ public class Url : Payload private readonly string url; /// - /// Generates a link. If not given, http/https protocol will be added. + /// Generates a link. If the protocol is not specified, the http protocol will be added. /// /// Link url target public Url(string url) @@ -321,7 +322,7 @@ public Url(string url) public override string ToString() { - return (!this.url.StartsWith("http") ? "http://" + this.url : this.url); + return (!this.url.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? "http://" + this.url : this.url); } } @@ -2012,6 +2013,7 @@ private void ProcessCommonFields(StringBuilder sb) } string strippedSecret = Secret.Replace(" ", ""); string escapedIssuer = null; + string escapedLabel = null; string label = null; if (!String40Methods.IsNullOrWhiteSpace(Issuer)) @@ -2023,18 +2025,22 @@ private void ProcessCommonFields(StringBuilder sb) escapedIssuer = Uri.EscapeDataString(Issuer); } - if (!String40Methods.IsNullOrWhiteSpace(Label) && Label.Contains(":")) + if (!String40Methods.IsNullOrWhiteSpace(Label)) { - throw new Exception("Label must not have a ':'"); + if (Label.Contains(":")) + { + throw new Exception("Label must not have a ':'"); + } + escapedLabel = Uri.EscapeDataString(Label); } - if (Label != null && Issuer != null) + if (escapedLabel != null && escapedIssuer != null) { - label = Issuer + ":" + Label; + label = escapedIssuer + ":" + escapedLabel; } - else if (Issuer != null) + else if (escapedIssuer != null) { - label = Issuer; + label = escapedIssuer; } if (label != null) diff --git a/QRCoder/PostscriptQRCode.cs b/QRCoder/PostscriptQRCode.cs index 710551d1..d0484a9b 100644 --- a/QRCoder/PostscriptQRCode.cs +++ b/QRCoder/PostscriptQRCode.cs @@ -1,4 +1,4 @@ -#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0 || NET6_0_WINDOWS +#if !NETSTANDARD1_3 using System; using System.Drawing; using static QRCoder.QRCodeGenerator; @@ -6,9 +6,6 @@ namespace QRCoder { -#if NET6_0_WINDOWS - [System.Runtime.Versioning.SupportedOSPlatform("windows")] -#endif public class PostscriptQRCode : AbstractQRCode, IDisposable { /// @@ -143,9 +140,6 @@ sc sc scale "; } -#if NET6_0_WINDOWS - [System.Runtime.Versioning.SupportedOSPlatform("windows")] -#endif public static class PostscriptQRCodeHelper { public static string GetQRCode(string plainText, int pointsPerModule, string darkColorHex, string lightColorHex, ECCLevel eccLevel, bool forceUtf8 = false, bool utf8BOM = false, EciMode eciMode = EciMode.Default, int requestedVersion = -1, bool drawQuietZones = true, bool epsFormat = false) @@ -157,5 +151,4 @@ public static string GetQRCode(string plainText, int pointsPerModule, string dar } } } - #endif \ No newline at end of file diff --git a/QRCoder/SvgQRCode.cs b/QRCoder/SvgQRCode.cs index e03ce5dc..81cc2486 100644 --- a/QRCoder/SvgQRCode.cs +++ b/QRCoder/SvgQRCode.cs @@ -1,4 +1,4 @@ -#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0 || NET6_0_WINDOWS +#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0_OR_GREATER using QRCoder.Extensions; using System; using System.Collections; @@ -11,9 +11,6 @@ namespace QRCoder { -#if NET6_0_WINDOWS - [System.Runtime.Versioning.SupportedOSPlatform("windows")] -#endif public class SvgQRCode : AbstractQRCode, IDisposable { /// @@ -270,13 +267,16 @@ public class SvgLogo private object _logoRaw; private bool _isEmbedded; - +#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0 || NET6_0_WINDOWS /// /// Create a logo object to be used in SvgQRCode renderer /// /// Logo to be rendered as Bitmap/rasterized graphic /// Degree of percentage coverage of the QR code by the logo /// If true, the background behind the logo will be cleaned +#if NET6_0_WINDOWS + [System.Runtime.Versioning.SupportedOSPlatform("windows")] +#endif public SvgLogo(Bitmap iconRasterized, int iconSizePercent = 15, bool fillLogoBackground = true) { _iconSizePercent = iconSizePercent; @@ -285,7 +285,7 @@ public SvgLogo(Bitmap iconRasterized, int iconSizePercent = 15, bool fillLogoBac using (var bitmap = new Bitmap(iconRasterized)) { bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); - _logoData = Convert.ToBase64String(ms.GetBuffer(), Base64FormattingOptions.None); + _logoData = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length, Base64FormattingOptions.None); } } _mediaType = MediaType.PNG; @@ -293,6 +293,7 @@ public SvgLogo(Bitmap iconRasterized, int iconSizePercent = 15, bool fillLogoBac _logoRaw = iconRasterized; _isEmbedded = false; } +#endif /// /// Create a logo object to be used in SvgQRCode renderer @@ -311,6 +312,22 @@ public SvgLogo(string iconVectorized, int iconSizePercent = 15, bool fillLogoBac _isEmbedded = iconEmbedded; } + /// + /// Create a logo object to be used in SvgQRCode renderer + /// + /// Logo to be rendered as PNG + /// Degree of percentage coverage of the QR code by the logo + /// If true, the background behind the logo will be cleaned + public SvgLogo(byte[] iconRasterized, int iconSizePercent = 15, bool fillLogoBackground = true) + { + _iconSizePercent = iconSizePercent; + _logoData = Convert.ToBase64String(iconRasterized, Base64FormattingOptions.None); + _mediaType = MediaType.PNG; + _fillLogoBackground = fillLogoBackground; + _logoRaw = iconRasterized; + _isEmbedded = false; + } + /// /// Returns the raw logo's data /// @@ -379,9 +396,6 @@ public enum MediaType : int } } -#if NET6_0_WINDOWS - [System.Runtime.Versioning.SupportedOSPlatform("windows")] -#endif public static class SvgQRCodeHelper { public static string GetQRCode(string plainText, int pixelsPerModule, string darkColorHex, string lightColorHex, ECCLevel eccLevel, bool forceUtf8 = false, bool utf8BOM = false, EciMode eciMode = EciMode.Default, int requestedVersion = -1, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute, SvgLogo logo = null) diff --git a/QRCoderTests/ArtQRCodeRendererTests.cs b/QRCoderTests/ArtQRCodeRendererTests.cs index 9742bb3a..b5734eed 100644 --- a/QRCoderTests/ArtQRCodeRendererTests.cs +++ b/QRCoderTests/ArtQRCodeRendererTests.cs @@ -23,11 +23,7 @@ public void can_create_standard_qrcode_graphic() var bmp = new ArtQRCode(data).GetGraphic(10); var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("11ebdda91b9632d016798cb6de2f5339"); -#else result.ShouldBe("cb38c3156eaf13cdfba699bdafc3a84c"); -#endif } [Fact] @@ -40,11 +36,7 @@ public void can_create_standard_qrcode_graphic_with_custom_finder() var bmp = new ArtQRCode(data).GetGraphic(10, Color.Black, Color.White, Color.Transparent, finderPatternImage: finder); var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("c54a7389ae995abc838f0d228acc3bad"); -#else result.ShouldBe("1102c0c6f235eaf4c3ac639f82f17bfa"); -#endif } [Fact] @@ -56,11 +48,7 @@ public void can_create_standard_qrcode_graphic_without_quietzone() var bmp = new ArtQRCode(data).GetGraphic(10, Color.Black, Color.White, Color.Transparent, drawQuietZones: false); var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("550f31b988ff12d5f8429ef19d9d5a0c"); -#else result.ShouldBe("632315c8695416fc82fe06a202688433"); -#endif } [Fact] @@ -74,11 +62,7 @@ public void can_create_standard_qrcode_graphic_with_background() var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("2caa9c0ee8fcb4a93841debb58cf41bc"); -#else result.ShouldBe("bbea08507282773175cfe7b52f0ddae4"); -#endif } [Fact] diff --git a/QRCoderTests/AsciiQRCodeRendererTests.cs b/QRCoderTests/AsciiQRCodeRendererTests.cs index 7ac2656b..b74bee07 100644 --- a/QRCoderTests/AsciiQRCodeRendererTests.cs +++ b/QRCoderTests/AsciiQRCodeRendererTests.cs @@ -14,8 +14,8 @@ public class AsciiQRCodeRendererTests [Category("QRRenderer/AsciiQRCode")] public void can_render_ascii_qrcode() { - var targetCode = " \n \n \n \n ██████████████ ██ ██ ██████████████ \n ██ ██ ██ ████ ██ ██ \n ██ ██████ ██ ██ ██ ██ ██ ██████ ██ \n ██ ██████ ██ ██ ██ ██████ ██ \n ██ ██████ ██ ██ ██ ██████ ██ \n ██ ██ ████████ ██ ██ \n ██████████████ ██ ██ ██ ██████████████ \n ██ ████ \n ██████████ ████ ████████ ██ ████ \n ████ ██ ██ ████ ████████ ██ \n ██ ██ ██████████ ██ ██ ██ ████ \n ██ ██ ████ ████ ████ \n ████████ ██████ ████ ██ ██ \n ████████ \n ██████████████ ████ ████ ██ ████ ████ \n ██ ██ ████████ \n ██ ██████ ██ ██ ██ ██ ██ ██ ██ \n ██ ██████ ██ ██████ ██ ██ \n ██ ██████ ██ ██ ██ ██ ██ ████ ████ \n ██ ██ ████ ████ ██ ██ \n ██████████████ ██████ ██ ██████ \n \n \n \n "; - + var targetCode = " \n \n \n \n ██████████████ ████ ██ ██████████████ \n ██ ██ ████ ██ ██ ██ \n ██ ██████ ██ ██ ██ ██ ██ ██████ ██ \n ██ ██████ ██ ██ ██ ██ ██████ ██ \n ██ ██████ ██ ██████████ ██ ██████ ██ \n ██ ██ ██ ██ \n ██████████████ ██ ██ ██ ██████████████ \n ██████████ \n ████ ██ ████ ██████ ██ ██████████ \n ██ ██ ██ ██ ██ ████ \n ████ ██████ ██████ ██████ ██ \n ████ ██ ██████ ██ ██ ██ \n ████ ████ ██ ██ ██ ██ ████ \n ██ ██ ██ ██ ██ \n ██████████████ ██ ████ ██████ ██ \n ██ ██ ██ ████ ██████ \n ██ ██████ ██ ██████ ████████ ██ ██ \n ██ ██████ ██ ██ ██ ████ \n ██ ██████ ██ ██████ ██ ██ ██ \n ██ ██ ██ ██ ██ ██████ \n ██████████████ ██ ██ ██ ██ ██ ██ \n \n \n \n "; + //Create QR code var gen = new QRCodeGenerator(); var data = gen.CreateQrCode("A05", QRCodeGenerator.ECCLevel.Q); @@ -28,8 +28,8 @@ public void can_render_ascii_qrcode() [Category("QRRenderer/AsciiQRCode")] public void can_render_ascii_qrcode_without_quietzones() { - var targetCode = "██████████████ ██ ██ ██████████████\n██ ██ ██ ████ ██ ██\n██ ██████ ██ ██ ██ ██ ██ ██████ ██\n██ ██████ ██ ██ ██ ██████ ██\n██ ██████ ██ ██ ██ ██████ ██\n██ ██ ████████ ██ ██\n██████████████ ██ ██ ██ ██████████████\n ██ ████ \n██████████ ████ ████████ ██ ████ \n████ ██ ██ ████ ████████ ██\n ██ ██ ██████████ ██ ██ ██ ████ \n██ ██ ████ ████ ████ \n ████████ ██████ ████ ██ ██\n ████████ \n██████████████ ████ ████ ██ ████ ████\n██ ██ ████████ \n██ ██████ ██ ██ ██ ██ ██ ██ ██\n██ ██████ ██ ██████ ██ ██ \n██ ██████ ██ ██ ██ ██ ██ ████ ████\n██ ██ ████ ████ ██ ██ \n██████████████ ██████ ██ ██████"; - + var targetCode = "██████████████ ████ ██ ██████████████\n██ ██ ████ ██ ██ ██\n██ ██████ ██ ██ ██ ██ ██ ██████ ██\n██ ██████ ██ ██ ██ ██ ██████ ██\n██ ██████ ██ ██████████ ██ ██████ ██\n██ ██ ██ ██\n██████████████ ██ ██ ██ ██████████████\n ██████████ \n ████ ██ ████ ██████ ██ ██████████\n██ ██ ██ ██ ██ ████\n ████ ██████ ██████ ██████ ██\n████ ██ ██████ ██ ██ ██ \n ████ ████ ██ ██ ██ ██ ████ \n ██ ██ ██ ██ ██ \n██████████████ ██ ████ ██████ ██ \n██ ██ ██ ████ ██████ \n██ ██████ ██ ██████ ████████ ██ ██\n██ ██████ ██ ██ ██ ████ \n██ ██████ ██ ██████ ██ ██ ██\n██ ██ ██ ██ ██ ██████\n██████████████ ██ ██ ██ ██ ██ ██"; + //Create QR code var gen = new QRCodeGenerator(); var data = gen.CreateQrCode("A05", QRCodeGenerator.ECCLevel.Q); @@ -42,7 +42,7 @@ public void can_render_ascii_qrcode_without_quietzones() [Category("QRRenderer/AsciiQRCode")] public void can_render_ascii_qrcode_with_custom_symbols() { - var targetCode = " \n \n \n \n \n \n \n \n XXXXXXXXXXXXXX XXXX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XXXX XXXXXXXXXXXXXX \n XX XX XXXXXX XX XX XX \n XX XX XXXXXX XX XX XX \n XX XXXXXX XX XXXXXXXX XX XXXXXX XX \n XX XXXXXX XX XXXXXXXX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XX XX XX XX \n XX XX XX XX XX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XXXXXXXX \n XXXXXXXX \n XX XXXXXX XXXXXX XX XX XX \n XX XXXXXX XXXXXX XX XX XX \n XX XXXXXX XXXX XXXXXXXX XXXXXX XX \n XX XXXXXX XXXX XXXXXXXX XXXXXX XX \n XX XX XX XX XX XX \n XX XX XX XX XX XX \n XX XX XX XX XXXXXX \n XX XX XX XX XXXXXX \n XX XXXXXXXX XXXX XX XXXXXXXX XX \n XX XXXXXXXX XXXX XX XXXXXXXX XX \n XX XXXXXXXX XXXX \n XX XXXXXXXX XXXX \n XXXXXXXXXXXXXX XXXXXXXX XX XXXXXX \n XXXXXXXXXXXXXX XXXXXXXX XX XXXXXX \n XX XX XXXXXX XXXXXXXX \n XX XX XXXXXX XXXXXXXX \n XX XXXXXX XX XX XXXX XX XXXX \n XX XXXXXX XX XX XXXX XX XXXX \n XX XXXXXX XX XXXX XXXXXXXX \n XX XXXXXX XX XXXX XXXXXXXX \n XX XXXXXX XX XX XXXXXXXX XX XXXXXX \n XX XXXXXX XX XX XXXXXXXX XX XXXXXX \n XX XX XX XXXX XX \n XX XX XX XXXX XX \n XXXXXXXXXXXXXX XX XXXXXX XXXX XXXX \n XXXXXXXXXXXXXX XX XXXXXX XXXX XXXX \n \n \n \n \n \n \n \n "; + var targetCode = " \n \n \n \n \n \n \n \n XXXXXXXXXXXXXX XX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XX XXXXXXXXXXXXXX \n XX XX XXXX XX XX \n XX XX XXXX XX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XX XXXXXX XX \n XX XX XX XX XX XX \n XX XX XX XX XX XX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XX XX \n XX XX \n XX XX XX XXXXXX XXXX XXXX XX \n XX XX XX XXXXXX XXXX XXXX XX \n XXXXXX XX XXXX XX XX XX XXXX \n XXXXXX XX XXXX XX XX XX XXXX \n XXXXXX XXXXXXXXXX XXXXXXXXXX \n XXXXXX XXXXXXXXXX XXXXXXXXXX \n XX XX XX XX XX XXXXXX XX XX \n XX XX XX XX XX XXXXXX XX XX \n XXXXXX XXXX XX XX XXXX XX XX \n XXXXXX XXXX XX XX XXXX XX XX \n XXXXXX XXXX XX XX \n XXXXXX XXXX XX XX \n XXXXXXXXXXXXXX XXXXXX XX \n XXXXXXXXXXXXXX XXXXXX XX \n XX XX XX XX XX \n XX XX XX XX XX \n XX XXXXXX XX XXXXXXXXXX XXXXXXXXXXXXXX \n XX XXXXXX XX XXXXXXXXXX XXXXXXXXXXXXXX \n XX XXXXXX XX XX XXXX XX XX XXXX \n XX XXXXXX XX XX XXXX XX XX XXXX \n XX XXXXXX XX XXXXXX XXXXXXXXXX \n XX XXXXXX XX XXXXXX XXXXXXXXXX \n XX XX XX XXXX XX XX XX \n XX XX XX XXXX XX XX XX \n XXXXXXXXXXXXXX XX XXXXXX XXXXXX \n XXXXXXXXXXXXXX XX XXXXXX XXXXXX \n \n \n \n \n \n \n \n "; //Create QR code var gen = new QRCodeGenerator(); @@ -65,7 +65,7 @@ public void can_instantate_parameterless() [Category("QRRenderer/AsciiQRCode")] public void can_render_ascii_qrcode_from_helper() { - var targetCode = " \n \n \n \n \n \n \n \n XXXXXXXXXXXXXX XXXX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XXXX XXXXXXXXXXXXXX \n XX XX XXXXXX XX XX XX \n XX XX XXXXXX XX XX XX \n XX XXXXXX XX XXXXXXXX XX XXXXXX XX \n XX XXXXXX XX XXXXXXXX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XX XX XX XX \n XX XX XX XX XX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XXXXXXXX \n XXXXXXXX \n XX XXXXXX XXXXXX XX XX XX \n XX XXXXXX XXXXXX XX XX XX \n XX XXXXXX XXXX XXXXXXXX XXXXXX XX \n XX XXXXXX XXXX XXXXXXXX XXXXXX XX \n XX XX XX XX XX XX \n XX XX XX XX XX XX \n XX XX XX XX XXXXXX \n XX XX XX XX XXXXXX \n XX XXXXXXXX XXXX XX XXXXXXXX XX \n XX XXXXXXXX XXXX XX XXXXXXXX XX \n XX XXXXXXXX XXXX \n XX XXXXXXXX XXXX \n XXXXXXXXXXXXXX XXXXXXXX XX XXXXXX \n XXXXXXXXXXXXXX XXXXXXXX XX XXXXXX \n XX XX XXXXXX XXXXXXXX \n XX XX XXXXXX XXXXXXXX \n XX XXXXXX XX XX XXXX XX XXXX \n XX XXXXXX XX XX XXXX XX XXXX \n XX XXXXXX XX XXXX XXXXXXXX \n XX XXXXXX XX XXXX XXXXXXXX \n XX XXXXXX XX XX XXXXXXXX XX XXXXXX \n XX XXXXXX XX XX XXXXXXXX XX XXXXXX \n XX XX XX XXXX XX \n XX XX XX XXXX XX \n XXXXXXXXXXXXXX XX XXXXXX XXXX XXXX \n XXXXXXXXXXXXXX XX XXXXXX XXXX XXXX \n \n \n \n \n \n \n \n "; + var targetCode = " \n \n \n \n \n \n \n \n XXXXXXXXXXXXXX XX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XX XXXXXXXXXXXXXX \n XX XX XXXX XX XX \n XX XX XXXX XX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XX XXXXXX XX \n XX XX XX XX XX XX \n XX XX XX XX XX XX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XX XX \n XX XX \n XX XX XX XXXXXX XXXX XXXX XX \n XX XX XX XXXXXX XXXX XXXX XX \n XXXXXX XX XXXX XX XX XX XXXX \n XXXXXX XX XXXX XX XX XX XXXX \n XXXXXX XXXXXXXXXX XXXXXXXXXX \n XXXXXX XXXXXXXXXX XXXXXXXXXX \n XX XX XX XX XX XXXXXX XX XX \n XX XX XX XX XX XXXXXX XX XX \n XXXXXX XXXX XX XX XXXX XX XX \n XXXXXX XXXX XX XX XXXX XX XX \n XXXXXX XXXX XX XX \n XXXXXX XXXX XX XX \n XXXXXXXXXXXXXX XXXXXX XX \n XXXXXXXXXXXXXX XXXXXX XX \n XX XX XX XX XX \n XX XX XX XX XX \n XX XXXXXX XX XXXXXXXXXX XXXXXXXXXXXXXX \n XX XXXXXX XX XXXXXXXXXX XXXXXXXXXXXXXX \n XX XXXXXX XX XX XXXX XX XX XXXX \n XX XXXXXX XX XX XXXX XX XX XXXX \n XX XXXXXX XX XXXXXX XXXXXXXXXX \n XX XXXXXX XX XXXXXX XXXXXXXXXX \n XX XX XX XXXX XX XX XX \n XX XX XX XXXX XX XX XX \n XXXXXXXXXXXXXX XX XXXXXX XXXXXX \n XXXXXXXXXXXXXX XX XXXXXX XXXXXX \n \n \n \n \n \n \n \n "; //Create QR code var asciiCode = AsciiQRCodeHelper.GetQRCode("A", 2, "X", " ", QRCodeGenerator.ECCLevel.Q); diff --git a/QRCoderTests/PayloadGeneratorTests.cs b/QRCoderTests/PayloadGeneratorTests.cs index f4406bb7..e3beda3c 100644 --- a/QRCoderTests/PayloadGeneratorTests.cs +++ b/QRCoderTests/PayloadGeneratorTests.cs @@ -317,6 +317,19 @@ public void wifi_should_build_wpa() generator.ToString().ShouldBe($"WIFI:T:WPA;S:MyWiFiSSID;P:7heP4assw0rd;;"); } + [Fact] + [Category("PayloadGenerator/WiFi")] + public void wifi_should_build_wpa2() + { + var ssid = "MyWiFiSSID"; + var password = "7heP4assw0rd"; + var authmode = PayloadGenerator.WiFi.Authentication.WPA2; + var hideSSID = false; + + var generator = new PayloadGenerator.WiFi(ssid, password, authmode, hideSSID); + + generator.ToString().ShouldBe($"WIFI:T:WPA2;S:MyWiFiSSID;P:7heP4assw0rd;;"); + } [Fact] [Category("PayloadGenerator/WiFi")] @@ -744,6 +757,18 @@ public void url_should_build_https() } + [Fact] + [Category("PayloadGenerator/Url")] + public void url_should_build_https_all_caps() + { + var url = "HTTPS://CODE-BUDE.NET"; + + var generator = new PayloadGenerator.Url(url); + + generator.ToString().ShouldBe("HTTPS://CODE-BUDE.NET"); + } + + [Fact] [Category("PayloadGenerator/Url")] public void url_should_add_http() @@ -2656,7 +2681,22 @@ public void one_time_password_generator_time_based_generates_with_standard_optio Label = "test@google.com", }; - pg.ToString().ShouldBe("otpauth://totp/Google:test@google.com?secret=pwq65q55&issuer=Google"); + pg.ToString().ShouldBe("otpauth://totp/Google:test%40google.com?secret=pwq65q55&issuer=Google"); + } + + + [Fact] + [Category("PayloadGenerator/OneTimePassword")] + public void one_time_password_generator_time_based_generates_with_standard_options_escapes_issuer_and_label() + { + var pg = new PayloadGenerator.OneTimePassword + { + Secret = "pwq6 5q55", + Issuer = "Google Google", + Label = "test/test@google.com", + }; + + pg.ToString().ShouldBe("otpauth://totp/Google%20Google:test%2Ftest%40google.com?secret=pwq65q55&issuer=Google%20Google"); } @@ -2673,7 +2713,23 @@ public void one_time_password_generator_hmac_based_generates_with_standard_optio Counter = 500, }; - pg.ToString().ShouldBe("otpauth://hotp/Google:test@google.com?secret=pwq65q55&issuer=Google&counter=500"); + pg.ToString().ShouldBe("otpauth://hotp/Google:test%40google.com?secret=pwq65q55&issuer=Google&counter=500"); + } + + [Fact] + [Category("PayloadGenerator/OneTimePassword")] + public void one_time_password_generator_hmac_based_generates_with_standard_options_escapes_issuer_and_label() + { + var pg = new PayloadGenerator.OneTimePassword + { + Secret = "pwq6 5q55", + Issuer = "Google Google", + Label = "test/test@google.com", + Type = PayloadGenerator.OneTimePassword.OneTimePasswordAuthType.HOTP, + Counter = 500, + }; + + pg.ToString().ShouldBe("otpauth://hotp/Google%20Google:test%2Ftest%40google.com?secret=pwq65q55&issuer=Google%20Google&counter=500"); } diff --git a/QRCoderTests/PngByteQRCodeRendererTests.cs b/QRCoderTests/PngByteQRCodeRendererTests.cs index 7be21684..0bba6e82 100644 --- a/QRCoderTests/PngByteQRCodeRendererTests.cs +++ b/QRCoderTests/PngByteQRCodeRendererTests.cs @@ -107,11 +107,7 @@ public void can_render_pngbyte_qrcode_color_without_quietzones() var bmp = (Bitmap)Image.FromStream(mStream); bmp.MakeTransparent(Color.Transparent); var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("75be11d582575617d2490c54b69e844e"); -#else result.ShouldBe("fbbc8255ebf3e4f4a1d21f0dd15f76f8"); -#endif } #endif } diff --git a/QRCoderTests/PostscriptQRCodeRendererTests.cs b/QRCoderTests/PostscriptQRCodeRendererTests.cs new file mode 100644 index 00000000..a71db527 --- /dev/null +++ b/QRCoderTests/PostscriptQRCodeRendererTests.cs @@ -0,0 +1,91 @@ +#if !NETCOREAPP1_1 +using QRCoder; +using QRCoderTests.Helpers; +using QRCoderTests.Helpers.XUnitExtenstions; +using Shouldly; +using System; +using System.Drawing; +using System.IO; +using System.Text.RegularExpressions; +using Xunit; + +namespace QRCoderTests +{ + public class PostscriptQRCodeRendererTests + { + [Fact] + [Category("QRRenderer/PostscriptQRCode")] + public void can_render_postscript_qrcode_simple() + { + //Create QR code + var gen = new QRCodeGenerator(); + var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.L); + var ps = new PostscriptQRCode(data).GetGraphic(5); + + var result = HelperFunctions.StringToHash(RemoveCreationDate(ps)); + result.ShouldBe("06b90d1e64bf022a248453e5f91101a0"); + } + + [Fact] + [Category("QRRenderer/PostscriptQRCode")] + public void can_render_postscript_qrcode_eps() + { + //Create QR code + var gen = new QRCodeGenerator(); + var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.L); + var ps = new PostscriptQRCode(data).GetGraphic(5, true); + + var result = HelperFunctions.StringToHash(RemoveCreationDate(ps)); + result.ShouldBe("50f6152cdb0b685595d80e7888712d3b"); + } + + [Fact] + [Category("QRRenderer/PostscriptQRCode")] + public void can_render_postscript_qrcode_size() + { + //Create QR code + var gen = new QRCodeGenerator(); + var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.L); + var ps = new PostscriptQRCode(data).GetGraphic(new Size(33, 33)); + + var result = HelperFunctions.StringToHash(RemoveCreationDate(ps)); + result.ShouldBe("49c7faaafef312eb4b6ea1fec195e63d"); + } + + [Fact] + [Category("QRRenderer/PostscriptQRCode")] + public void can_render_postscript_qrcode_size_no_quiet_zones() + { + //Create QR code + var gen = new QRCodeGenerator(); + var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.L); + var ps = new PostscriptQRCode(data).GetGraphic(new Size(50, 50), false); + + var result = HelperFunctions.StringToHash(RemoveCreationDate(ps)); + result.ShouldBe("9bfa0468e125d9815a39902133a10762"); + } + + [Fact] + [Category("QRRenderer/PostscriptQRCode")] + public void can_render_postscript_qrcode_colors() + { + //Create QR code + var gen = new QRCodeGenerator(); + var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.L); + var ps = new PostscriptQRCode(data).GetGraphic(5, Color.Red, Color.Blue); + + var result = HelperFunctions.StringToHash(RemoveCreationDate(ps)); + result.ShouldBe("2e001d7f67a446eb1b5df32ff5321808"); + } + + private static string RemoveCreationDate(string text) + { + // Regex pattern to match lines that start with %%CreationDate: followed by any characters until the end of the line + string pattern = @"%%CreationDate:.*\r?\n?"; + + // Use Regex.Replace to remove matching lines + return Regex.Replace(text, pattern, string.Empty, RegexOptions.Multiline); + } + } +} +#endif \ No newline at end of file diff --git a/QRCoderTests/QRCodeRendererTests.cs b/QRCoderTests/QRCodeRendererTests.cs index b7414e2b..ed77ec5f 100644 --- a/QRCoderTests/QRCodeRendererTests.cs +++ b/QRCoderTests/QRCodeRendererTests.cs @@ -46,11 +46,7 @@ public void can_create_qrcode_standard_graphic_without_quietzones() var bmp = new QRCode(data).GetGraphic(5, Color.Black, Color.White, false); var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("329e1664f57cbe7332d8d4db04c1d480"); -#else result.ShouldBe("d703e54a0ba541c6ea69e3d316e394e7"); -#endif } @@ -65,11 +61,7 @@ public void can_create_qrcode_with_transparent_logo_graphic() var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.Transparent, icon: (Bitmap)Image.FromFile(HelperFunctions.GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png")); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("ee65d96c3013f6032b561cc768251eef"); -#else result.ShouldBe("150f8fc7dae4487ba2887d2b2bea1c25"); -#endif } [Fact] @@ -83,11 +75,7 @@ public void can_create_qrcode_with_non_transparent_logo_graphic() //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("1d718f06f904af4a46748f02af2d4eec"); -#else result.ShouldBe("c46a7ec51bf978d7a882059c322ca69d"); -#endif } [Fact] @@ -102,11 +90,7 @@ public void can_create_qrcode_with_logo_and_with_transparent_border() var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.Transparent, icon: logo, iconBorderWidth: 6); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("ee65d96c3013f6032b561cc768251eef"); -#else result.ShouldBe("150f8fc7dae4487ba2887d2b2bea1c25"); -#endif } [Fact] @@ -121,11 +105,7 @@ public void can_create_qrcode_with_logo_and_with_standard_border() var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.White, icon: logo, iconBorderWidth: 6); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("52207bd86ca5a532fb2095dbaa0ae04c"); -#else result.ShouldBe("1c926ea1d48f42fdf8e6f1438b774cdd"); -#endif } [Fact] @@ -140,11 +120,7 @@ public void can_create_qrcode_with_logo_and_with_custom_border() var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.Transparent, icon: logo, iconBorderWidth: 6, iconBackgroundColor: Color.DarkGreen); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); -#if NET35_OR_GREATER || NET40_OR_GREATER - result.ShouldBe("d2f20d34a973d92b9c3e05db1393b331"); -#else result.ShouldBe("9a06bfbb72df999b6290b5af5c4037cb"); -#endif } diff --git a/QRCoderTests/SvgQRCodeRendererTests.cs b/QRCoderTests/SvgQRCodeRendererTests.cs index b0620594..0981e6e2 100644 --- a/QRCoderTests/SvgQRCodeRendererTests.cs +++ b/QRCoderTests/SvgQRCodeRendererTests.cs @@ -1,4 +1,4 @@ -#if !NETCOREAPP1_1 && !NET6_0 +#if !NETCOREAPP1_1 using System; using Xunit; using QRCoder; @@ -103,9 +103,10 @@ public void can_render_svg_qrcode_without_quietzones_hex() result.ShouldBe("4ab0417cc6127e347ca1b2322c49ed7d"); } +#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0 || NET6_0_WINDOWS [Fact] [Category("QRRenderer/SvgQRCode")] - public void can_render_svg_qrcode_with_png_logo() + public void can_render_svg_qrcode_with_png_logo_bitmap() { //Create QR code var gen = new QRCodeGenerator(); @@ -119,7 +120,27 @@ public void can_render_svg_qrcode_with_png_logo() var svg = new SvgQRCode(data).GetGraphic(10, Color.DarkGray, Color.White, logo: logoObj); var result = HelperFunctions.StringToHash(svg); - result.ShouldBe("78e02e8ba415f15817d5ed88c4afca31"); + result.ShouldBe("78e02e8ba415f15817d5ed88c4afca31"); + } +#endif + + [Fact] + [Category("QRRenderer/SvgQRCode")] + public void can_render_svg_qrcode_with_png_logo_bytearray() + { + //Create QR code + var gen = new QRCodeGenerator(); + var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); + + //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 + var logoBitmap = System.IO.File.ReadAllBytes(GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png"); + var logoObj = new SvgQRCode.SvgLogo(iconRasterized: logoBitmap, 15); + logoObj.GetMediaType().ShouldBe(SvgQRCode.SvgLogo.MediaType.PNG); + + var svg = new SvgQRCode(data).GetGraphic(10, Color.DarkGray, Color.White, logo: logoObj); + + var result = HelperFunctions.StringToHash(svg); + result.ShouldBe("7d53f25af04e52b20550deb2e3589e96"); } [Fact] diff --git a/readme.md b/readme.md index 7e0e6ac7..d0a22a59 100644 --- a/readme.md +++ b/readme.md @@ -40,13 +40,13 @@ _(More information on how to use Github Packages in Nuget Package Manager can be ## Usage -You only need five lines of code, to generate and view your first QR code. +You only need four lines of code, to generate and view your first QR code. ```csharp QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode("The text which should be encoded.", QRCodeGenerator.ECCLevel.Q); -QRCode qrCode = new QRCode(qrCodeData); -Bitmap qrCodeImage = qrCode.GetGraphic(20); +QRCode qrCode = new PngByteQRCode(qrCodeData); +byte[] qrCodeImage = qrCode.GetGraphic(20); ``` ### Optional parameters and overloads