如何在 C# 中验证二维码校验和并应用容错机制

This article was translated from English: Does it need improvement?
Translated
View the article in English

处理现实世界输入(包括打印标签、相机拍摄的图像或扫描的文档)的二维码管道会遇到损坏严重而无法解码的符号,以及通过校验和但未通过业务验证的结果。

里德-所罗门纠错技术能够自动解决解码过程中的物理损坏问题。 如果无法恢复某个符号,则结果集合为空而不是部分结果。 应用层验证是独立的,它涉及在进一步处理之前检查解码后的值是否非空、是否符合预期格式或是否包含有效的 URI。

本文介绍了如何使用IronQR库验证二维码校验和并应用容错检查。

快速入门:验证二维码校验和

读取二维码并检查解码是否成功:非空结果表示里德-所罗门校验和通过。

  1. 使用 NuGet 包管理器安装 https://www.nuget.org/packages/IronQR

    PM > Install-Package IronQR
  2. 复制并运行这段代码。

    using IronQr;
    using IronSoftware.Drawing;
    
    var reader = new QrReader();
    IEnumerable<QrResult> results = reader.Read(new QrImageInput("label.png"));
    
    if (!results.Any())
    {
        Console.WriteLine("No QR code detected or decoding failed.");
        return;
    }
    
    Console.WriteLine(results.First().Value);
  3. 部署到您的生产环境中进行测试

    通过免费试用立即在您的项目中开始使用IronQR

    arrow pointer

验证二维码校验和

二维码采用里德-所罗门纠错码来检测并修复编码数据的损坏。 校正水平(低为 7%,中为 15%,四分位数为 25%,高为 30%)决定了可以丢失但仍能恢复的码字百分比。

在读取方面,校验和验证在解码过程中内部运行。 QrResult 类没有公开 confidence 属性; 如果集合中存在结果,则校验和通过。 如果解码失败,则集合为空。

输入

一个编码为 https://ironsoftware.com/ 的 QR 码产品标签,采用中度纠错生成,代表在运输过程中可能被触碰或轻微刮擦的标签。

二维码编码 https://ironsoftware.com 用作校验和验证的输入
:path=/static-assets/qr/content-code-examples/how-to/checksum-and-fault-tolerance/checksum-validation.cs
using IronQr;
using IronSoftware.Drawing;

var reader = new QrReader();
IEnumerable<QrResult> results = reader.Read(new QrImageInput("damaged-label.png"));

// Reed-Solomon decoding is pass/fail — presence in results means valid checksum
if (!results.Any())
{
    // Decoding failed entirely — damage exceeded the error correction capacity
    Console.WriteLine("QR code could not be decoded. Consider re-scanning or using a higher error correction level at generation time.");
    return;
}

foreach (QrResult result in results)
{
    // Decoded successfully — validate the content matches expected format
    if (string.IsNullOrWhiteSpace(result.Value))
    {
        Console.WriteLine("QR decoded but produced an empty value.");
        continue;
    }

    Console.WriteLine($"Valid QR: {result.Value}");
}
Imports IronQr
Imports IronSoftware.Drawing

Dim reader As New QrReader()
Dim results As IEnumerable(Of QrResult) = reader.Read(New QrImageInput("damaged-label.png"))

' Reed-Solomon decoding is pass/fail — presence in results means valid checksum
If Not results.Any() Then
    ' Decoding failed entirely — damage exceeded the error correction capacity
    Console.WriteLine("QR code could not be decoded. Consider re-scanning or using a higher error correction level at generation time.")
    Return
End If

For Each result As QrResult In results
    ' Decoded successfully — validate the content matches expected format
    If String.IsNullOrWhiteSpace(result.Value) Then
        Console.WriteLine("QR decoded but produced an empty value.")
        Continue For
    End If

    Console.WriteLine($"Valid QR: {result.Value}")
Next
$vbLabelText   $csharpLabel

输出

控制台显示解码后的值 https://ironsoftware.com/,这证实里德-所罗门解码成功,且有效载荷已完整恢复。

终端输出显示已解码的二维码:https://ironsoftware.com

为了提高抗物理损坏能力,请生成具有更高纠错级别的二维码。 高级版本可以恢复高达 30% 的数据丢失,但代价是符号更大。


处理二维码读取中的格式感知

IronQR支持三种 QR 编码格式:标准 QR、Micro QR 和矩形 Micro QR。 扫描仪在读取过程中会自动检测格式。 扫描完成后,QrResult.QrType 字段会以枚举值的形式提供检测到的格式。

对于 PDF 文件,请使用 QrPdfInput 代替 QrImageInput。 扫描模式决定了速度与准确性之间的平衡:Auto 结合了机器学习检测与经典扫描,OnlyDetectionModel 仅使用机器学习模型以加快处理速度,而 OnlyBasicScan 则完全跳过机器学习,适用于高质量的预处理图像。

输入

PNG 产品标签(左)和 JPEG 相机拍摄图像(右),演示了对两种常见输入类型进行格式感知读取的功能。

product-label.png QR code used as input for format-aware reading
camera-capture.jpg JPEG QR code simulating a camera capture
:path=/static-assets/qr/content-code-examples/how-to/checksum-and-fault-tolerance/format-awareness.cs
using IronQr;
using IronSoftware.Drawing;
using IronQr.Enum;

// Read from an image file with ML + classic scan (default)
var reader = new QrReader();
IEnumerable<QrResult> results = reader.Read(new QrImageInput("product-label.png"));

foreach (QrResult result in results)
{
    // Inspect the detected QR format
    Console.WriteLine($"Format: {result.QrType}");   // QRCode, MicroQRCode, or RMQRCode
    Console.WriteLine($"Value:  {result.Value}");

    // Url is non-null only if Value is a valid URI
    if (result.Url != null)
    {
        Console.WriteLine($"URI:    {result.Url.AbsoluteUri}");
    }

    // Corner coordinates for positional context
    Console.WriteLine($"Corners: {result.Points.Length} points detected");
}

// Read from a bitmap with ML-only mode for faster throughput
var bitmap = AnyBitmap.FromFile("camera-capture.jpg");
var fastResults = reader.Read(new QrImageInput(bitmap, QrScanMode.OnlyDetectionModel));
Imports IronQr
Imports IronSoftware.Drawing
Imports IronQr.Enum

' Read from an image file with ML + classic scan (default)
Dim reader As New QrReader()
Dim results As IEnumerable(Of QrResult) = reader.Read(New QrImageInput("product-label.png"))

For Each result As QrResult In results
    ' Inspect the detected QR format
    Console.WriteLine($"Format: {result.QrType}")   ' QRCode, MicroQRCode, or RMQRCode
    Console.WriteLine($"Value:  {result.Value}")

    ' Url is non-null only if Value is a valid URI
    If result.Url IsNot Nothing Then
        Console.WriteLine($"URI:    {result.Url.AbsoluteUri}")
    End If

    ' Corner coordinates for positional context
    Console.WriteLine($"Corners: {result.Points.Length} points detected")
Next

' Read from a bitmap with ML-only mode for faster throughput
Dim bitmap As AnyBitmap = AnyBitmap.FromFile("camera-capture.jpg")
Dim fastResults = reader.Read(New QrImageInput(bitmap, QrScanMode.OnlyDetectionModel))
$vbLabelText   $csharpLabel

输出

控制台显示产品标签的检测到的格式、解码值、解析的 URI 和角数,然后显示相机捕获的快速扫描结果计数。

终端输出显示:格式:QRCode,值:https://ironsoftware.com/product,URI,以及检测到的角点:4 个。

当应用程序要求特定格式时,QrType 字段会很有帮助。 例如,一个只生成标准二维码的仓库系统可以过滤掉意外的微型二维码或矩形微型二维码检测结果,这些结果可能表示噪声或无关标签。 每种格式都有其独特的容量特性:标准 QR 码最多支持 7,089 个数字字符,Micro QR 码最多支持 35 个字符,而矩形 Micro QR 码则采用矩形外形,适用于标签空间有限的情况。


对二维码结果应用空值检查

QrReader.Read 若未找到QR码,则返回一个空集合; 它永远不会返回 null。 但是,各个结果属性仍需验证。 例如,如果解码后的字符串不是有效的 URI,则 Value 可能为空,而 Url 将返回 null。

一个完善的验证模式会在将数据传递给另一个系统之前检查三个方面:集合计数、值完整性和类型或 URI 有效性。

输入

一张没有二维码的空白白色图像,代表一批混合文档中的一页,其中一些页面没有机器可读标签。

一张空白的白色图像(不含二维码)用作空值检查演示的输入
:path=/static-assets/qr/content-code-examples/how-to/checksum-and-fault-tolerance/null-checking-validator.cs
using IronQr;
using IronSoftware.Drawing;
using System.Collections.Generic;
using System.Linq;

public static class QrValidator
{
    public static List<QrResult> GetValidResults(
        string imagePath,
        QrEncoding? expectedFormat = null)
    {
        var reader = new QrReader();
        IEnumerable<QrResult> results = reader.Read(new QrImageInput(imagePath));

        // Guard: no QR codes detected
        if (!results.Any())
            return new List<QrResult>();

        return results
            .Where(r => !string.IsNullOrWhiteSpace(r.Value))
            .Where(r => expectedFormat == null || r.QrType == expectedFormat)
            .ToList();
    }
}

// Usage — only accept standard QR codes with non-empty values
var validated = QrValidator.GetValidResults(
    "shipping-manifest.png",
    expectedFormat: QrEncoding.QRCode);

if (validated.Count == 0)
{
    Console.WriteLine("No valid QR codes found for processing.");
    return;
}

foreach (var qr in validated)
{
    // Safe for downstream: value is non-empty, format is verified
    SendToInventoryApi(qr.Value, qr.Url?.AbsoluteUri);
}
Imports IronQr
Imports IronSoftware.Drawing
Imports System.Collections.Generic
Imports System.Linq

Public Module QrValidator
    Public Function GetValidResults(
        imagePath As String,
        Optional expectedFormat As QrEncoding? = Nothing) As List(Of QrResult)

        Dim reader As New QrReader()
        Dim results As IEnumerable(Of QrResult) = reader.Read(New QrImageInput(imagePath))

        ' Guard: no QR codes detected
        If Not results.Any() Then
            Return New List(Of QrResult)()
        End If

        Return results _
            .Where(Function(r) Not String.IsNullOrWhiteSpace(r.Value)) _
            .Where(Function(r) expectedFormat Is Nothing OrElse r.QrType = expectedFormat) _
            .ToList()
    End Function
End Module

' Usage — only accept standard QR codes with non-empty values
Dim validated = QrValidator.GetValidResults(
    "shipping-manifest.png",
    expectedFormat:=QrEncoding.QRCode)

If validated.Count = 0 Then
    Console.WriteLine("No valid QR codes found for processing.")
    Return
End If

For Each qr In validated
    ' Safe for downstream: value is non-empty, format is verified
    SendToInventoryApi(qr.Value, qr.Url?.AbsoluteUri)
Next qr
$vbLabelText   $csharpLabel

输出

控制台显示验证器的空结果响应:未检测到二维码,因此集合为空,没有数据继续进行下游处理。

终端输出显示:未找到可处理的有效二维码。

验证器返回一个空列表(绝不返回 null),从而免除了调用处对 null 的检查。可选的 expectedFormat 参数充当格式门控,因此调用代码仅接收符合预期格式类型的结果。 Url 属性使用空条件运算符,可安全地处理 URI 和非 URI 负载。

对于异步工作流,对 ReadAsync 应用相同的验证模式:等待调用并对结果集合使用相同的检查。


进一步阅读

-错误纠正级别:写入时恢复能力和纠正级别配置。 -如何读取二维码:输入格式选项和读取模式。

准备生产时,请查看许可选项

点击这里下载完整的 ChecksumFaultToleranceTest 控制台应用程序项目。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

准备开始了吗?
Nuget 下载 63,625 | 版本: 2026.4 刚刚发布
Still Scrolling Icon

还在滚动吗?

想快速获得证据? PM > Install-Package IronQR
运行示例 观看您的 URL 变成 QR 代码。