如何在C#中验证条码校验和并使用格式感知阅读
条形码校验和有助于检测替换错误。 例如,EAN-13 标签中一个数字颠倒就可能导致包裹被送到错误的仓库。 格式感知读取通过将解码器限制为预期的符号体系,提供了额外的验证层。 这种方法通过跳过不必要的格式检测器来减少背景噪声造成的误报并缩短扫描时间。
IronBarcode在解码过程中会自动执行校验和验证。 每种条码编码的校验位算法默认运行,失败的条码会在返回结果之前被丢弃。 BarcodeReaderOptions.ExpectBarcodeTypes 属性将读取限制在特定格式,而 RemoveFalsePositive 则针对模糊读取添加了二次扫描。
本指南说明了如何验证BarCode校验和、将读取结果限制在预期格式内,以及如何将这两种技术结合起来,利用 BarcodeReaderOptions 构建分层质量控制点。
快速入门:使用校验和与格式约束验证条码
将 BarcodeReaderOptions 与 ExpectBarcodeTypes 及 RemoveFalsePositive 配合使用,通过自动校验和验证将读取限制在预期的条码符号范围内。
: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)
最小工作流程(5 个步骤)
- 从NuGet下载IronBarcode库
- 创建
BarcodeReaderOptions实例 - 将
ExpectBarcodeTypes设置为管道中存在的符号集 - 启用
RemoveFalsePositive进行二次验证 - 调用
BarcodeReader.Read进行解码,解码过程中会自动验证校验和。
如何验证条码校验和?
IronBarcode在解码过程中会根据每种符号体系的规范验证校验和。 例如,读取 EAN-13 条形码时,模块10 校验位由前 12 位数字计算得出,并与第 13 位进行比较。 如果数字不匹配,BARCODE将被静默拒绝,且不会出现在 BarcodeResults 集合中。 这种方法适用于所有带有强制校验位的格式,包括 UPC-A、UPC-E、EAN-8、Code128、ITF 等。
这种隐式模型不同于那些公开显式开关的库。 下表比较了这两种方法:
| 方面 | IronBarcode | Aspose.BarCode |
|---|---|---|
| 验证触发 | 自动运行;每次解码期间运行 | 显式: 校验和Validation.On / Off / Default |
| 需要开发者操作 | 无;无效条形码已从结果中排除。 | 读取条形码前,请设置BarcodeSettings.校验和Validation |
| 校验和禁用 | 未公开;强制格式始终强制执行校验和。 | 是的; 校验和Validation.Off会跳过验证 |
| 可选校验和格式(Code39) | 使用Confidence + RemoveFalsePositive来过滤低质量读取数据 | 显式启用Enable校验和.是 |
| 故障行为 | 结果中静默遗漏条码 | 条形码可能带有单独的校验和值,以便人工检查。 |
对于带有可选校验和的条码(如 Code39),该库采用置信度评分机制,并使用 RemoveFalsePositive 代替校验和开关。
输入
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
输出
成功之路
仓库货架BarCode在第 0 页显示为 RACK-A1-LOT-7382。该BarCode通过了 85% 的置信度阈值并通过校验和验证,因此显示为 BarcodeResults。
故障路径
将 ConfidenceThreshold 的值调高至其 0.7 的默认值之上,将进一步收紧针对 Code39 等可选校验和符号体系的校验阈值。
校验和验证完成后,下一步是将读取器限制为管道所需的条形码格式。
如何使用格式感知条码读取?
BarcodeEncoding 枚举是一个标志类型,允许使用位或运算符组合多种格式。 设置 ExpectBarcodeTypes 将受众限定为这些格式,并跳过对其他格式的检测。
| Value | 翻译类别 | 说明 | 校验和 |
|---|---|---|---|
BarcodeEncoding.All | 元 | 所有支持的格式(默认行为) | 每格式 |
BarcodeEncoding.AllOneDimensional | 元 | 所有线性(1D)格式包括堆叠 | 每格式 |
BarcodeEncoding.AllTwoDimensional | 元 | 所有矩阵/网格(二维)格式 | 每格式 |
BarcodeEncoding.Code128 | 1D | 高密度字母数字字符集(物流、运输) | 强制(加权模块103) |
BarcodeEncoding.EAN13 | 1D | 零售产品识别码,13 位数字 | 强制(模块10) |
BarcodeEncoding.QRCode | 二维 | 高容量矩阵(URL、结构化数据) | 里德-所罗门 ECC |
BarcodeEncoding.Code39 | 1D | 字母数字(国防、汽车) | 可选(Mod43) |
BarcodeEncoding.UPCA | 1D | 北美零售,12位数 | 强制(模块10) |
BarcodeEncoding.DataMatrix | 二维 | 紧凑型矩阵(电子、制药) | 里德-所罗门 ECC |
BarcodeEncoding.PDF417 | 二维 | 堆叠(身份证、交通卡) | 里德-所罗门 ECC |
除了速度之外,限制格式集还起到验证门的作用:即使条形码实际存在于图像中,任何未列出的符号体系的条形码也会被排除在结果之外。
输入
Code128 运输标签(成功路径)和不符合 Code128 限制的二维码(失败路径)。
shipping-label.png(成功路径 — 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
输出
成功之路
该运单的值为 SHIP-2024-00438。 受限读取立即检测到了它,因为 Code128 是过滤器所期望的,而广泛读取在所有格式中都确认了相同的结果。
故障路径
受限读取结果为空是验证信号,而不是错误; 记录差异以供审核。
对于混合使用条形码类型的流程(例如,装箱单上同时包含 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
}
每个返回的 BarcodeResult.BarcodeType 标识了已解码的格式,以便进行后续路由。
哪些符号集支持校验和验证?
并非所有条码格式都以相同方式使用校验和。 下表将常见符号与相应的错误检测特征进行映射,以此确定针对每种格式应如何设置 ConfidenceThreshold 和 RemoveFalsePositive 的严格程度:
| 符号集 | 校验和类型 | 是否强制? | 建议 |
|---|---|---|---|
| EAN-13 / EAN-8 | 模块10 | 是 | 默认设置已足够;始终强制执行校验和。 |
| UPC-A / UPC-E | 模块10 | 是 | 默认设置已足够;写入时校验位自动更正 |
| Code128 | 加权模块103 | 是 | 默认设置已足够;按规范要求必须使用。 |
| Code39 | Mod43 | 可选 | 将ConfidenceThreshold提升到0.8+并启用RemoveFalsePositive |
| Codabar | Mod16 | 可选 | 与 Code39 相同;使用置信度作为质量门控 |
| ITF | 模块10 | 可选 | 为交错格式启用RemoveFalsePositive |
| 二维码/数据矩阵 | 里德-所罗门 ECC | 总是 | 结构误差修正;无需额外配置 |
| PDF417 | 里德-所罗门 ECC | 总是 | 与 QR/DataMatrix 相同;纠错功能是固有的。 |
对于 QR、DataMatrix 和 PDF417 等二维符号体系,纠错功能已集成到编码结构中。 这些格式无需依赖简单的校验位即可从部分损坏中恢复。 在机器学习检测阶段,ConfidenceThreshold 仍适用,而解码步骤则得益于该条码符号内置的冗余机制。
既然我们已经了解了这两种技术,让我们将它们合并成一个可用于生产的单一验证模式。
如何结合校验和与格式约束?
该生产就绪模式将 ConfidenceThreshold 和 Speed 设置为单个 BarcodeReaderOptions 对象。 它们共同构成了一个分层门:格式约束缩小了搜索空间,校验和验证确保了数据完整性,置信度阈值过滤了边缘解码,而误报消除则增加了一次二次验证。
输入
从作为成功路径的 pos-scans/ 目录中扫描三个 BARCODE:两个 EAN-13 和一个 UPC-A。 使用 Code128 仓库货架标签作为失败路径——EAN-13/UPC-A 约束会拒绝该标签,并记录一条 REJECT 日志。
pos-scan-1.png(成功)
pos-scan-2.png(成功)
pos-scan-3.png(成功)
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
输出
成功之路
三张POS扫描图像全部通过。 读取器返回了 4006381333931 和 012345678905 的值。 每个都与"EAN13"匹配 | 上层控制区 | UPCE` 滤波器具有有效的 模块10 校验和,置信度高于 0.8。
故障路径
将 MinScanLines 设置为 3 会增加一维BarCode生效所需的最小匹配扫描行数; 默认值为 2。提高此值可降低噪声扫描线出现虚假读取的风险,但可能会导致漏检细小或部分损坏的条形码。 在零售 POS 环境中,如果标签打印清晰,则取值为 3 是一个保守的选择,可以在不影响吞吐量的情况下加强验证。
读后 BarcodeType 断言属于深度防御机制:ExpectBarcodeTypes 已进行过滤,但显式检查能明确意图,并在不增加运行时开销的情况下捕获配置漂移。在速度优化方面,ReadingSpeed.Faster 适用于干净的机器打印标签; Detailed 和 ExtremeDetail 能够修复受损或光线不足的 BARCODE,但会延长扫描时间。
我的下一个步骤是什么?
本文介绍了 IronBarcode 的隐式校验和验证模型、用于格式受限读取的 BarcodeEncoding 标志枚举,以及使用 RemoveFalsePositive 及 MinScanLines 作为分层质量门槛的组合验证模式。
欲了解更多信息,请探索以下资源:
- IronBarcode教程——条码读取 进行端到端读取指南。
- 详细说明
RemoveFalsePositive机制的误报预防措施。 - 信心阈值示例 用于基于ML的检测调整。
BarcodeResult属性参考的输出数据格式。- 图像校正教程 通过滤镜提高解码准确率。
- BarcodeReaderOptions API 参考手册 提供完整配置文档。
- BarcodeEncoding API 参考手册 列出所有支持的符号集。
常见问题解答
什么是条码校验和验证?
条码校验和验证是通过将计算的校验和与条码中编码的值进行比对,以确保条码数据准确性的过程。这有助于检测扫描过程中的错误。
IronBarcode如何处理校验和验证?
IronBarcode隐式处理校验和验证,通过计算条码数据的校验和并与编码的校验和进行比对,以确保在扫描过程中的数据完整性。
什么是BarcodeEncoding过滤器?
IronBarcode中的BarcodeEncoding过滤器允许您在扫描时指定要读取或忽略的条码格式,从而通过专注于特定的条码类型来实现更精确和高效的条码处理。
IronBarcode可以进行结合验证吗?
可以,IronBarcode可以通过在扫描过程中检查条码的校验和和格式同时进行结合验证,从而确保只有有效且格式正确的条码被处理。
使用IronBarcode是否可以在C#中按格式限制条码读取?
可以,IronBarcode允许您通过指定要包含或排除的格式来限制条码读取,确保您的应用程序仅处理相关的条码类型。
为什么在条码处理中格式感知读取很重要?
格式感知读取很重要,因为它允许您的应用程序仅处理特定类型的条码,通过忽略不相关或不支持的条码格式,提高速度和准确性。
如何在IronBarcode中实现格式感知读取?
要在IronBarcode中实现格式感知读取,请使用BarcodeEncoding过滤器指定您希望读取的条码格式。通过库的API可以实现对条码扫描需求的精确控制。
使用IronBarcode进行条码验证的好处是什么?
IronBarcode在条码验证中提供多项好处,包括稳健的校验和验证、格式感知读取,以及处理多种条码标准的能力,确保条码处理中的高精度和灵活性。
在项目中实现IronBarcode需要哪些编程技能?
了解C#编程的基础知识就足以在项目中实现IronBarcode,因为它提供了简单的方法和全面的文档来指导开发人员。
IronBarcode适合小项目和大型企业应用吗?
IronBarcode被设计为可扩展且多功能,适合需要强大条码解决方案的小项目和大型企业应用。

