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

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

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

IronBarcode在解码过程中会自动执行校验和验证。 每种条码编码的校验位算法默认运行,失败的条码会在返回结果之前被丢弃。 RemoveFalsePositive添加次要扫描以识别模糊读取。

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

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

使用BarcodeReaderOptions,以将读取限制为预期符号,自动校验和验证。

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

对于提供可选校验和的符号(如Code39),库使用置信度评分和RemoveFalsePositive而不是校验和切换。

输入

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

编码 RACK-A1-LOT-7382 的 Code128 条形码,用作仓库货架扫描的输入

warehouse-rack.png(成功路径)

无条形码的空白图像,用于触发空结果路径

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页上,仓库货架条形码返回值为BarcodeResults中。

故障路径

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

ConfidenceThreshold提高到0.7的默认值以上,可进一步严格审查提供可选校验和的符号,如Code39。

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


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

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

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

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

输入

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

编码 SHIP-2024-00438 的 Code128 条形码,用作运输标签的输入

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

用作仅限 Code128 约束读取的格式不匹配失败路径的二维码

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标识解码的格式,支持下游路由。

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

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

按符号集划分的校验和特性
符号集校验和类型是否强制?建议
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,而解码步骤受益于符号内置冗余。

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


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

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

输入

三个来自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(成功)

编码 RACK-A1-LOT-7382 的 Code128 条形码,用作组合验证失败路径的输入

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扫描图像全部通过。 读取器返回值为012345678905。 每个都与"EAN13"匹配 | 上层控制区 | UPCE` 滤波器具有有效的 模块10 校验和,置信度高于 0.8。

故障路径

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

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

读取后的ReadingSpeed.Faster适用于清晰的机器打印标签; ExtremeDetail在更长的扫描时间下恢复损坏或照明不佳的条形码。


我的下一个步骤是什么?

本文涵盖了IronBarcode的隐式校验和验证模型、用于格式约束读取的MinScanLines的组合验证模式。

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

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

常见问题解答

什么是条码校验和验证?

条码校验和验证是通过将计算的校验和与条码中编码的值进行比对,以确保条码数据准确性的过程。这有助于检测扫描过程中的错误。

IronBarcode如何处理校验和验证?

IronBarcode隐式处理校验和验证,通过计算条码数据的校验和并与编码的校验和进行比对,以确保在扫描过程中的数据完整性。

什么是BarcodeEncoding过滤器?

IronBarcode中的BarcodeEncoding过滤器允许您在扫描时指定要读取或忽略的条码格式,从而通过专注于特定的条码类型来实现更精确和高效的条码处理。

IronBarcode可以进行结合验证吗?

可以,IronBarcode可以通过在扫描过程中检查条码的校验和和格式同时进行结合验证,从而确保只有有效且格式正确的条码被处理。

使用IronBarcode是否可以在C#中按格式限制条码读取?

可以,IronBarcode允许您通过指定要包含或排除的格式来限制条码读取,确保您的应用程序仅处理相关的条码类型。

为什么在条码处理中格式感知读取很重要?

格式感知读取很重要,因为它允许您的应用程序仅处理特定类型的条码,通过忽略不相关或不支持的条码格式,提高速度和准确性。

如何在IronBarcode中实现格式感知读取?

要在IronBarcode中实现格式感知读取,请使用BarcodeEncoding过滤器指定您希望读取的条码格式。通过库的API可以实现对条码扫描需求的精确控制。

使用IronBarcode进行条码验证的好处是什么?

IronBarcode在条码验证中提供多项好处,包括稳健的校验和验证、格式感知读取,以及处理多种条码标准的能力,确保条码处理中的高精度和灵活性。

在项目中实现IronBarcode需要哪些编程技能?

了解C#编程的基础知识就足以在项目中实现IronBarcode,因为它提供了简单的方法和全面的文档来指导开发人员。

IronBarcode适合小项目和大型企业应用吗?

IronBarcode被设计为可扩展且多功能,适合需要强大条码解决方案的小项目和大型企业应用。

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

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

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

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

准备开始了吗?
Nuget 下载 2,317,217 | 版本: 2026.7 刚刚发布
Still Scrolling Icon

还在滚动吗?

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