如何在 C# 中验证条形码校验和并使用格式感知读取

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

条形码校验和有助于检测替换错误。 例如,EAN-13 标签中一个数字颠倒就可能导致包裹被送到错误的仓库。 格式感知读取通过将解码器限制为预期的符号体系,提供了额外的验证层。 这种方法通过跳过不必要的格式检测器来减少背景噪声造成的误报并缩短扫描时间。

IronBarcode在解码过程中会自动执行校验和验证。 每种条码编码的校验位算法默认运行,失败的条码会在返回结果之前被丢弃。 BarcodeReaderOptions.ExpectBarcodeTypes 属性将读取限制为特定格式,而 RemoveFalsePositive 则增加了对模糊读取的二次扫描。

本指南解释了如何验证条形码校验和,将读取限制为预期格式,并将这两种技术结合到一个分层质量门中,使用 BarcodeReaderOptions

快速入门:使用校验和与格式约束验证条码

配置 BarcodeReaderOptionsExpectBarcodeTypesRemoveFalsePositive,以将读取限制为预期符号体系,并自动进行校验和验证。

:path=/static-assets/barcode/content-code-examples/how-to/checksum-and-format-validation/quickstart.cs
using IronBarCode;

// Format-constrained read with false-positive removal.
// Limit the decoder to EAN-13 and Code128; checksums are
// validated automatically and failures are silently discarded.
var options = new BarcodeReaderOptions
{
    ExpectBarcodeTypes  = BarcodeEncoding.EAN13 | BarcodeEncoding.Code128,
    RemoveFalsePositive = true,
    Speed               = ReadingSpeed.Balanced
};

BarcodeResults results = BarcodeReader.Read("label.png", options);
Imports IronBarCode

' Format-constrained read with false-positive removal.
' Limit the decoder to EAN-13 and Code128; checksums are
' validated automatically and failures are silently discarded.
Dim options As New BarcodeReaderOptions With {
    .ExpectBarcodeTypes = BarcodeEncoding.EAN13 Or BarcodeEncoding.Code128,
    .RemoveFalsePositive = True,
    .Speed = ReadingSpeed.Balanced
}

Dim results As BarcodeResults = BarcodeReader.Read("label.png", options)
$vbLabelText   $csharpLabel

如何验证条码校验和?

IronBarcode在解码过程中会根据每种符号体系的规范验证校验和。 例如,读取 EAN-13 条形码时,模块10 校验位由前 12 位数字计算得出,并与第 13 位进行比较。 如果数字不匹配,则条形码将被默默拒绝,并且不会出现在 BarcodeResults 集合中。 这种方法适用于所有带有强制校验位的格式,包括 UPC-A、UPC-E、EAN-8、Code128、ITF 等。

这种隐式模型不同于那些公开显式开关的库。 下表比较了这两种方法:

校验和验证模型对比: IronBarcode与 Aspose.Barcode
方面IronBarcodeAspose.BarCode
验证触发自动运行;每次解码期间运行显式: 校验和Validation.On / Off / Default
需要开发者操作无;无效条形码已从结果中排除。读取条形码前,请设置BarcodeSettings.校验和Validation
校验和禁用未公开;强制格式始终强制执行校验和。是的; 校验和Validation.Off会跳过验证
可选校验和格式(Code39)使用Confidence + RemoveFalsePositive来过滤低质量读取数据显式启用Enable校验和.是
故障行为结果中静默遗漏条码条形码可能带有单独的校验和值,以便人工检查。

对于具有可选校验和的符号体系(例如 Code39),该库使用置信度评分和 RemoveFalsePositive 而不是校验和切换。

输入

Code128 仓库货架标签(成功路径)和没有条形码的空白图像(失败路径)。

Code128 barcode encoding RACK-A1-LOT-7382 used as the warehouse rack scan input

warehouse-rack.png(成功路径)

Blank white image with no barcode to trigger the empty result path

blank-no-barcode.png(失败路径——无条形码)

:path=/static-assets/barcode/content-code-examples/how-to/checksum-and-format-validation/checksum-confidence.cs
using IronBarCode;

// Constrain reads to 1D formats and enable secondary verification.
// ConfidenceThreshold rejects decodes where the ML detector falls below 85%,
// acting as a quality gate for optional-checksum symbologies like Code39.
var options = new BarcodeReaderOptions
{
    ExpectBarcodeTypes  = BarcodeEncoding.AllOneDimensional,
    RemoveFalsePositive = true,
    ConfidenceThreshold = 0.85,
    Speed               = ReadingSpeed.Detailed
};

BarcodeResults results = BarcodeReader.Read("warehouse-rack.png", options);

foreach (BarcodeResult result in results)
{
    // Each result has passed checksum validation (mandatory formats)
    // and the 85% confidence threshold, so no additional filtering is needed.
    Console.WriteLine($"[{result.BarcodeType}] {result.Value}  page={result.PageNumber}");
}

if (results.Count == 0)
{
    Console.Error.WriteLine("No valid barcodes found. Possible causes:");
    Console.Error.WriteLine("  - Check digit mismatch (barcode silently rejected)");
    Console.Error.WriteLine("  - Confidence below 85% threshold");
    Console.Error.WriteLine("  - Format not in ExpectBarcodeTypes");
}
Imports IronBarCode

' Constrain reads to 1D formats and enable secondary verification.
' ConfidenceThreshold rejects decodes where the ML detector falls below 85%,
' acting as a quality gate for optional-checksum symbologies like Code39.
Dim options As New BarcodeReaderOptions With {
    .ExpectBarcodeTypes = BarcodeEncoding.AllOneDimensional,
    .RemoveFalsePositive = True,
    .ConfidenceThreshold = 0.85,
    .Speed = ReadingSpeed.Detailed
}

Dim results As BarcodeResults = BarcodeReader.Read("warehouse-rack.png", options)

For Each result As BarcodeResult In results
    ' Each result has passed checksum validation (mandatory formats)
    ' and the 85% confidence threshold, so no additional filtering is needed.
    Console.WriteLine($"[{result.BarcodeType}] {result.Value}  page={result.PageNumber}")
Next

If results.Count = 0 Then
    Console.Error.WriteLine("No valid barcodes found. Possible causes:")
    Console.Error.WriteLine("  - Check digit mismatch (barcode silently rejected)")
    Console.Error.WriteLine("  - Confidence below 85% threshold")
    Console.Error.WriteLine("  - Format not in ExpectBarcodeTypes")
End If
$vbLabelText   $csharpLabel

输出

成功之路

控制台输出显示 Code128 RACK-A1-LOT-7382 的解码置信度高于阈值。

仓库货架条形码在第 0 页返回为 RACK-A1-LOT-7382。它通过了 85% 的置信度阈值并通过了校验和验证,因此显示在 BarcodeResults 中。

故障路径

控制台输出显示警告:未找到空白图像输入的有效条形码

ConfidenceThreshold 的值提高到其默认值 0.7 以上,可以进一步收紧 Code39 等可选校验和符号体系的此限制。

校验和验证完成后,下一步是将读取器限制为管道所需的条形码格式。


如何使用格式感知条码读取?

BarcodeEncoding 枚举类型为标志类型,允许使用按位或运算符组合多种格式。 设置 ExpectBarcodeTypes 会将读取器限制为这些格式,并跳过对其他格式的检测。

常用的BarcodeEncoding值
编码类别说明校验和
BarcodeEncoding.All所有支持的格式(默认行为)每格式
BarcodeEncoding.AllOneDimensional所有线性(1D)格式包括堆叠每格式
BarcodeEncoding.AllTwoDimensional所有矩阵/网格(二维)格式每格式
BarcodeEncoding.Code1281D高密度字母数字字符集(物流、运输)强制(加权模块103)
BarcodeEncoding.EAN131D零售产品识别码,13 位数字强制(模块10)
BarcodeEncoding.QRCode二维高容量矩阵(URL、结构化数据)里德-所罗门 ECC
BarcodeEncoding.Code391D字母数字(国防、汽车)可选(Mod43)
BarcodeEncoding.UPCA1D北美零售,12位数强制(模块10)
BarcodeEncoding.DataMatrix二维紧凑型矩阵(电子、制药)里德-所罗门 ECC
BarcodeEncoding.PDF417二维堆叠(身份证、交通卡)里德-所罗门 ECC

除了速度之外,限制格式集还起到验证门的作用:即使条形码实际存在于图像中,任何未列出的符号体系的条形码也会被排除在结果之外。

输入

Code128 运输标签(成功路径)和不符合 Code128 限制的二维码(失败路径)。

Code128 barcode encoding SHIP-2024-00438 used as the shipping label input

shipping-label.png(成功路径 — Code128 符合约束)

QR code used as the format-mismatch failure path for the Code128-only constrained read

qr-format-mismatch.png(失败路径——二维码被仅支持 Code128 的过滤器拒绝)

:path=/static-assets/barcode/content-code-examples/how-to/checksum-and-format-validation/format-constrained.cs
using IronBarCode;

// Constrained read: only Code128 barcodes are returned.
// Faster because the reader skips all other format detectors.
var constrainedOptions = new BarcodeReaderOptions
{
    ExpectBarcodeTypes     = BarcodeEncoding.Code128,
    Speed                  = ReadingSpeed.Faster,
    ExpectMultipleBarcodes = false
};

// Broad read: all supported formats are scanned.
// Useful for verification or when the image format is unknown.
var broadOptions = new BarcodeReaderOptions
{
    ExpectBarcodeTypes     = BarcodeEncoding.All,
    Speed                  = ReadingSpeed.Detailed,
    ExpectMultipleBarcodes = true
};

string imagePath = "shipping-label.png";

BarcodeResults constrained = BarcodeReader.Read(imagePath, constrainedOptions);
Console.WriteLine($"Constrained: {constrained.Count} Code128 barcode(s) found");

BarcodeResults broad = BarcodeReader.Read(imagePath, broadOptions);
Console.WriteLine($"Broad: {broad.Count} barcode(s) found across all formats");

foreach (BarcodeResult result in broad)
{
    Console.WriteLine($"  [{result.BarcodeType}] {result.Value}");
}
Imports IronBarCode

' Constrained read: only Code128 barcodes are returned.
' Faster because the reader skips all other format detectors.
Dim constrainedOptions As New BarcodeReaderOptions With {
    .ExpectBarcodeTypes = BarcodeEncoding.Code128,
    .Speed = ReadingSpeed.Faster,
    .ExpectMultipleBarcodes = False
}

' Broad read: all supported formats are scanned.
' Useful for verification or when the image format is unknown.
Dim broadOptions As New BarcodeReaderOptions With {
    .ExpectBarcodeTypes = BarcodeEncoding.All,
    .Speed = ReadingSpeed.Detailed,
    .ExpectMultipleBarcodes = True
}

Dim imagePath As String = "shipping-label.png"

Dim constrained As BarcodeResults = BarcodeReader.Read(imagePath, constrainedOptions)
Console.WriteLine($"Constrained: {constrained.Count} Code128 barcode(s) found")

Dim broad As BarcodeResults = BarcodeReader.Read(imagePath, broadOptions)
Console.WriteLine($"Broad: {broad.Count} barcode(s) found across all formats")

For Each result As BarcodeResult In broad
    Console.WriteLine($"  [{result.BarcodeType}] {result.Value}")
Next
$vbLabelText   $csharpLabel

输出

成功之路

控制台输出显示受限读取找到 1 个 Code128 条形码,宽读取结果也证实了这一点。

发货标签的值为 SHIP-2024-00438。 受限读取立即检测到了它,因为 Code128 是过滤器所期望的,而广泛读取在所有格式中都确认了相同的结果。

故障路径

控制台输出显示,对二维码图像进行受限读取返回 0 个结果。

受限读取结果为空是验证信号,而不是错误; 记录差异以供审核。

对于混合使用条形码类型的流程(例如,装箱单上同时包含 EAN-13 产品代码和 Code128 跟踪编号),请将预期格式结合起来:

:path=/static-assets/barcode/content-code-examples/how-to/checksum-and-format-validation/multi-format-combine.cs
using IronBarCode;

// Combine multiple format flags with | to scan for more than one symbology
// in a single pass. Each BarcodeResult.BarcodeType identifies which format
// was decoded, enabling downstream routing logic per symbology.
var options = new BarcodeReaderOptions
{
    ExpectBarcodeTypes     = BarcodeEncoding.EAN13 | BarcodeEncoding.Code128,
    ExpectMultipleBarcodes = true
};
Imports IronBarCode

' Combine multiple format flags with Or to scan for more than one symbology
' in a single pass. Each BarcodeResult.BarcodeType identifies which format
' was decoded, enabling downstream routing logic per symbology.
Dim options As New BarcodeReaderOptions With {
    .ExpectBarcodeTypes = BarcodeEncoding.EAN13 Or BarcodeEncoding.Code128,
    .ExpectMultipleBarcodes = True
}
$vbLabelText   $csharpLabel

每个返回的 BarcodeResult.BarcodeType 标识了解码后的格式,从而实现了下游路由。

哪些符号集支持校验和验证?

并非所有条码格式都以相同方式使用校验和。 下表将常用符号体系与其错误检测特性对应起来,从而说明如何针对每种格式设置 ConfidenceThresholdRemoveFalsePositive

按符号集划分的校验和特性
符号集校验和类型是否强制?建议
EAN-13 / EAN-8模块10默认设置已足够;始终强制执行校验和。
UPC-A / UPC-E模块10默认设置已足够;写入时校验位自动更正
Code128加权模块103默认设置已足够;按规范要求必须使用。
Code39Mod43可选ConfidenceThreshold提升到0.8+并启用RemoveFalsePositive
CodabarMod16可选与 Code39 相同;使用置信度作为质量门控
ITF模块10可选为交错格式启用RemoveFalsePositive
二维码/数据矩阵里德-所罗门 ECC总是结构误差修正;无需额外配置
PDF417里德-所罗门 ECC总是与 QR/DataMatrix 相同;纠错功能是固有的。

对于 QR、DataMatrix 和 PDF417 等二维符号体系,纠错功能已集成到编码结构中。 这些格式无需依赖简单的校验位即可从部分损坏中恢复。 ConfidenceThreshold 在 ML 检测阶段仍然适用,而解码步骤则受益于符号系统的内置冗余。

既然我们已经了解了这两种技术,让我们将它们合并成一个可用于生产的单一验证模式。


如何结合校验和与格式约束?

生产就绪模式集 ConfidenceThresholdSpeed 位于单个 BarcodeReaderOptions 对象中。 它们共同构成了一个分层门:格式约束缩小了搜索空间,校验和验证确保了数据完整性,置信度阈值过滤了边缘解码,而误报消除则增加了一次二次验证。

输入

成功路径使用了来自 pos-scans/ 目录的三个 POS 扫描条形码:两个 EAN-13 和一个 UPC-A。 Code128 仓库货架标签被用作故障路径——EAN-13/UPC-A 约束拒绝它,并记录了 REJECT 行。

EAN-13 barcode encoding 5901234123471 used as POS scan input 1

pos-scan-1.png(成功)

EAN-13 barcode encoding 4006381333931 used as POS scan input 2

pos-scan-2.png(成功)

UPC-A barcode encoding 012345678905 used as POS scan input 3

pos-scan-3.png(成功)

Code128 barcode encoding RACK-A1-LOT-7382 used as the combined-validation failure path input

warehouse-rack.png(失败——代码128被拒绝)

:path=/static-assets/barcode/content-code-examples/how-to/checksum-and-format-validation/combined-validation.cs
using IronBarCode;

// Layered validation for retail POS: EAN-13, UPC-A, and UPC-E only.
// Each property adds a distinct filter to the read pipeline.
var options = new BarcodeReaderOptions
{
    // Layer 1: format constraint, accept only retail symbologies
    ExpectBarcodeTypes = BarcodeEncoding.EAN13 | BarcodeEncoding.UPCA | BarcodeEncoding.UPCE,

    // Layer 2: confidence threshold, reject decodes below 80%
    ConfidenceThreshold = 0.8,

    // Layer 3: false-positive removal, runs a secondary verification pass
    RemoveFalsePositive = true,

    Speed                  = ReadingSpeed.Balanced,
    ExpectMultipleBarcodes = false,

    // Require 3 agreeing scan lines to reduce phantom reads from noisy images
    MinScanLines = 3
};

string[] scanFiles = Directory.GetFiles("pos-scans/", "*.png");

foreach (string file in scanFiles)
{
    BarcodeResults results = BarcodeReader.Read(file, options);

    if (results.Count == 0)
    {
        // No barcode passed all validation layers
        Console.Error.WriteLine($"REJECT {Path.GetFileName(file)}: "
            + "no valid EAN-13/UPC barcode (checksum, confidence, or format mismatch)");
        continue;
    }

    BarcodeResult primary = results.First();

    // Post-read assertion: verify the decoded format matches expectations.
    // ExpectBarcodeTypes already constrains the reader; this check documents
    // intent and surfaces unexpected results during future changes.
    if (primary.BarcodeType != BarcodeEncoding.EAN13
        && primary.BarcodeType != BarcodeEncoding.UPCA
        && primary.BarcodeType != BarcodeEncoding.UPCE)
    {
        Console.Error.WriteLine($"UNEXPECTED FORMAT {Path.GetFileName(file)}: "
            + $"got {primary.BarcodeType}, expected EAN-13/UPC");
        continue;
    }

    Console.WriteLine($"OK {Path.GetFileName(file)}: [{primary.BarcodeType}] {primary.Value}");
}
Imports IronBarCode
Imports System.IO

' Layered validation for retail POS: EAN-13, UPC-A, and UPC-E only.
' Each property adds a distinct filter to the read pipeline.
Dim options As New BarcodeReaderOptions With {
    ' Layer 1: format constraint, accept only retail symbologies
    .ExpectBarcodeTypes = BarcodeEncoding.EAN13 Or BarcodeEncoding.UPCA Or BarcodeEncoding.UPCE,

    ' Layer 2: confidence threshold, reject decodes below 80%
    .ConfidenceThreshold = 0.8,

    ' Layer 3: false-positive removal, runs a secondary verification pass
    .RemoveFalsePositive = True,

    .Speed = ReadingSpeed.Balanced,
    .ExpectMultipleBarcodes = False,

    ' Require 3 agreeing scan lines to reduce phantom reads from noisy images
    .MinScanLines = 3
}

Dim scanFiles As String() = Directory.GetFiles("pos-scans/", "*.png")

For Each file As String In scanFiles
    Dim results As BarcodeResults = BarcodeReader.Read(file, options)

    If results.Count = 0 Then
        ' No barcode passed all validation layers
        Console.Error.WriteLine($"REJECT {Path.GetFileName(file)}: " &
            "no valid EAN-13/UPC barcode (checksum, confidence, or format mismatch)")
        Continue For
    End If

    Dim primary As BarcodeResult = results.First()

    ' Post-read assertion: verify the decoded format matches expectations.
    ' ExpectBarcodeTypes already constrains the reader; this check documents
    ' intent and surfaces unexpected results during future changes.
    If primary.BarcodeType <> BarcodeEncoding.EAN13 AndAlso
       primary.BarcodeType <> BarcodeEncoding.UPCA AndAlso
       primary.BarcodeType <> BarcodeEncoding.UPCE Then
        Console.Error.WriteLine($"UNEXPECTED FORMAT {Path.GetFileName(file)}: " &
            $"got {primary.BarcodeType}, expected EAN-13/UPC")
        Continue For
    End If

    Console.WriteLine($"OK {Path.GetFileName(file)}: [{primary.BarcodeType}] {primary.Value}")
Next
$vbLabelText   $csharpLabel

输出

成功之路

控制台输出显示所有 3 个 POS 扫描条形码均已接受,状态为 OK,并已解码。

三张POS扫描图像全部通过。 读取器返回了 4006381333931012345678905 的值。 每个都与"EAN13"匹配 | 上层控制区 | UPCE` 滤波器具有有效的 模块10 校验和,置信度高于 0.8。

故障路径

控制台输出显示仓库货架上的 Code128 条形码被 EAN-13/UPC-A 过滤器拒绝

MinScanLines 设置为 3 会增加 1D 条形码有效所需的最小一致扫描线数; 默认值为 2。提高此值可降低噪声扫描线出现虚假读取的风险,但可能会导致漏检细小或部分损坏的条形码。 在零售 POS 环境中,如果标签打印清晰,则取值为 3 是一个保守的选择,可以在不影响吞吐量的情况下加强验证。

读取后的 BarcodeType 断言是一种纵深防御:ExpectBarcodeTypes 已经进行了过滤,但显式检查记录了意图,并在不增加运行时成本的情况下捕获了配置偏差。为了进行速度调优,ReadingSpeed.Faster 适用于干净的机器打印标签; DetailedExtremeDetail 可以恢复损坏或光线不足的条形码,但代价是扫描时间更长。


我的下一个步骤是什么?

本文介绍了 IronBarcode 的隐式校验和验证模型、格式受限读取的 BarcodeEncoding 标志枚举,以及使用 RemoveFalsePositiveMinScanLines 作为分层质量门的组合验证模式。

欲了解更多信息,请探索以下资源:

获取免费试用许可证在真实环境中测试所有功能,或在管道准备好投入生产时查看许可选项

常见问题解答

What is barcode checksum validation?

Barcode checksum validation is a process that ensures the accuracy of barcode data by verifying the calculated checksum against the value encoded within the barcode. This helps in detecting errors in the scanning process.

How does IronBarcode handle checksum validation?

IronBarcode implicitly handles checksum validation by calculating the checksum for the barcode data and verifying it against the encoded checksum, ensuring data integrity during the scanning process.

What are BarcodeEncoding filters?

BarcodeEncoding filters in IronBarcode allow you to specify which barcode formats to read or ignore during scanning, enabling more accurate and efficient barcode processing by focusing on specific barcode types.

Can IronBarcode perform combined validation?

Yes, IronBarcode can perform combined validation by checking both the checksum and the format of barcodes during the scanning process, ensuring that only valid and correctly formatted barcodes are processed.

Is it possible to constrain barcode reads by format in C# with IronBarcode?

Yes, IronBarcode allows you to constrain barcode reads by specifying the formats you want to include or exclude, ensuring that your application processes only relevant barcode types.

Why is format-aware reading important in barcode processing?

Format-aware reading is important because it allows your application to process only specific types of barcodes, improving speed and accuracy by ignoring irrelevant or unsupported barcode formats.

How do I implement format-aware reading in IronBarcode?

To implement format-aware reading in IronBarcode, use BarcodeEncoding filters to specify the barcode formats you wish to read. This can be done through the library's API, which allows for precise control over barcode scanning requirements.

What are the benefits of using IronBarcode for barcode validation?

IronBarcode offers several benefits for barcode validation, including robust checksum verification, format-aware reading, and the ability to handle a wide range of barcode standards, ensuring high accuracy and flexibility in barcode processing.

Darrius Serrant
全栈软件工程师(WebOps)

Darrius Serrant 拥有迈阿密大学的计算机科学学士学位,目前在 Iron Software 担任全栈 WebOps 市场工程师。从小就被编码吸引,他认为计算机既神秘又易于接触,使其成为创意和问题解决的理想媒介。

在 Iron Software,Darrius 喜欢创造新事物,并简化复杂概念以使其更易理解。作为我们常驻的开发者之一,他还自愿教授学生,与下一代分享他的专业知识。

对于 Darrius 来说,他的工作令人满意,因为它被重视并产生真正的影响。

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

还在滚动吗?

想快速获得证据? PM > Install-Package BarCode
运行示例 观看您的字符串变成 BarCode。