Respect Validation 中 NfeAccessKey 校验器实战:巴西电子发票(NFe)访问密钥验证与算法源码剖析
后端开发工具【免费下载链接】ValidationThe most awesome validation engine ever created for PHP项目地址https://gitcode.com/gh_mirrors/va/Validation点击查看免费下载Respect Validation 内置了面向巴西电子发票Nota Fiscal EletrônicaNFe的专用校验器NfeAccessKey用于验证 44 位 NFe 访问密钥access key的真实性。本文以 NfeAccessKey 文档 为主线结合 实现源码 与单元、特性测试讲解其用法、校验码算法、消息模板机制及链式 API 组合方式帮助读者在 PHP 项目中直接落地巴西税务单据校验场景。校验器概览与适用场景NfeAccessKey()是一个无参数校验器专门验证巴西电子发票访问密钥NFe access key。该密钥是巴西税务体系NF-e中每张电子发票的唯一标识字符串由 44 位数字组成。在源码中本校验器被归类为Identifications身份/证件识别系列同类校验器还包括 Cnh、Cnpj、Cpf、Pis、Imei、Isbn、Luhn 等见 validators 目录索引。它的校验能力不仅限于格式而是通过内置的模 11 校验位算法验证密钥的真伪能拦截位数不符、随机拼凑或伪造的密钥适用于订单系统、财务系统、电商平台对巴西发票数据的入库前校验。快速上手基础用法直接通过v::nfeAccessKey()即可获取校验器实例再调用assert()对输入进行断言v::nfeAccessKey()-assert(52060433009911002506550120000007800267301615); // 校验通过无异常抛出 v::nfeAccessKey()-assert(31841136830118868211870485416765268625116906); // → 31841136830118868211870485416765268625116906 must be a NFe access key第一个示例是合法的 44 位密钥与 单元测试 中的有效输入一致校验顺利通过第二个示例位数虽然也是 44 位但校验位计算不合法assert()抛出ValidationException默认错误信息为... must be a NFe access key。除了assert()ValidatorBuilder 还提供多种结果处理方式可根据场景选择方法行为说明assert($input)校验失败抛异常收集全部校验错误内部以AllOf组合评估见 ValidatorBuilder::evaluatecheck($input)校验失败抛异常短路求值遇首个失败即停止evaluateShortCircuit见 ValidatorBuildervalidate($input)返回结果对象不抛异常返回ResultQuery供程序化判断isValid($input)返回布尔值仅返回是否通过true/false需要快速判断单个密钥是否合法时用v::nfeAccessKey()-isValid($input)最简洁需要拿到完整错误信息时用assert()或validate()。链式 API 与组合用法Mixin 体系Respect Validation 通过 Mixin 体系为每个校验器生成丰富的链式变体。与nfeAccessKey相关的组合方法已遍布构建器与链类中例如v::notNfeAccessKey()— 否定校验等价于v::not(v::nfeAccessKey())见 NotBuilderv::nullOrNfeAccessKey()— 输入为null时直接通过见 NullOrBuilderv::undefOrNfeAccessKey()— 未定义/缺失时直接通过见 UndefOrBuilderv::allNfeAccessKey()— 对数组或Traversable的每个元素都执行校验见 AllBuilderv::keyNfeAccessKey(key)— 校验数组中指定键见 KeyBuilderv::propertyNfeAccessKey(prop)— 校验对象中指定属性见 PropertyBuilder对应地Chain类中还存在notNfeAccessKey()、allNfeAccessKey()、keyNfeAccessKey()等实例方法见 NotChain、AllChain、KeyChain支持$v-allNfeAccessKey()这类中间链式调用。典型组合示例// 批量校验发票列表中的每个密钥 v::allOf( v::each(v::nfeAccessKey()), // 每个元素都是合法 NFe 密钥 v::notEmpty() )-assert($invoiceKeys); // 表单数组场景密钥允许为空但非空时必须合法 v::keyOptional(nfe_access_key, v::nullOr(v::nfeAccessKey())) -assert($_POST);源码级剖析44 位校验码算法实现位于 src/Validators/NfeAccessKey.php类声明为final class NfeAccessKey extends Simple源码注释引用了巴西官方规范Manual de Integração do Contribuinte v4.0.1www.nfe.fazenda.gov.br。其校验逻辑分三步1. 类型与长度预检if (!is_scalar($input)) { return false; } if (mb_strlen((string) $input) ! 44) { return false; }isValid()首先拒绝一切非标量输入数组、对象、null、布尔值等直接返回false再以mb_strlen确认字符串恰为 44 位。这与 单元测试 中的无效用例[]、stdClass、null、true完全对应。2. 加权求和前 43 位数字按特定权重序列加权末位第 44 位是校验位权重为 0for ($i 0, $z 5, $m 43; $i $m; $i) { $z $i $m ? $z - 1 1 ? 9 : $z - 1 : 0; $w[] $z; }权重序列从 5 开始递减减到 1 时跳回 9 重新递减即循环模式5, 4, 3, 2, 9, 8, 7, 6, 5, 4, ...第 43 位校验位权重为 0。随后计算for ($i 0, $s 0, $k 44; $i $k; $i) { $s $digits[$i] * $w[$i]; }即s Σ(第 i 位数字 × 第 i 位权重)i 从 0 到 42因为第 43 位权重为 0。3. 模 11 校验位比对$s - 11 * floor($s / 11); // 等价于 $s % 11 $v $s 0 || $s 1 ? 0 : 11 - $s; return $v $digits[43]; // 与末位校验数字比对先取s对 11 的余数余数为 0 或 1 时校验数字取 0否则校验数字为11 - 余数最后与密钥第 44 位数字比对相等才通过。这套算法是巴西 NF-e 官方文档规定的标准校验位算法NfeAccessKey是它在 Respect Validation 中的直接实现。基类与评估入口NfeAccessKey继承自 Simple该抽象基类只要求实现isValid(mixed $input): bool并统一提供evaluate()将结果包装为Result对象Result::of(...)从而无缝接入assert()/validate()/isValid()等上层 API。这也是所有简单校验器无构造参数的通用扩展点。消息模板与占位符NfeAccessKey通过 PHP 8 属性声明内置了两套消息模板默认与反转由 Template 属性 驱动NfeAccessKey::TEMPLATE_STANDARDModeTemplatedefault{{subject}} must be a NFe access keyinverted{{subject}} must not be a NFe access key源码中的属性声明为#[Template( {{subject}} must be a NFe access key, {{subject}} must not be a NFe access key, )] final class NfeAccessKey extends Simple其中default是正向校验失败时的信息inverted则用于否定场景。当使用v::not(v::nfeAccessKey())且输入实际是合法密钥时会输出反转模板消息。这一点由 特性测试 直接验证v::not(v::nfeAccessKey())-assert(52060433009911002506550120000007800267301615); // → 52060433009911002506550120000007800267301615 must not be a NFe access key模板占位符PlaceholderDescriptionsubjectThe validated input or the custom validator name (if specified).{{subject}}会被替换为被校验的输入值或自定义的校验器名称若通过命名机制指定。关于占位符的插值管道与国际化翻译可进一步参考 placeholder-pipes 文档 与 translation 文档。若需自定义错误文案可在assert()/check()的第二个参数传入模板字符串或Throwable见 ValidatorBuilder 方法签名。测试验证与版本演进仓库为该校验器提供了完备的双层测试单元测试tests/unit/Validators/NfeAccessKeyTest.php通过数据提供器覆盖 1 个有效输入和 24 个无效输入后者包括 14 个位数不符/校验位错误的字符串、[]、stdClass、null、true等非标量类型完整验证了长度预检与模 11 算法的每个分支。特性测试tests/feature/Validators/NfeAccessKeyTest.php验证正向/反向断言产生的单条消息与完整消息getFullMessage()格式。版本变化记录在文档 Changelog 中3.0.0变更了消息模板体系0.6.0首次引入该校验器。相关校验器NFe 访问密钥常与巴西其他身份/票据校验器配合使用官方文档建议参考Cnh — 巴西驾照号Cnpj — 巴西企业法人登记号Cpf — 巴西个人纳税人登记号实际项目中一个巴西订单往往需要同时校验Cpf/Cnpj与NfeAccessKey可通过v::allOf()组合成一条校验规则链统一抛错、统一处理保证发票数据的完整性。赞分享后端开发工具【免费下载链接】ValidationThe most awesome validation engine ever created for PHP项目地址https://gitcode.com/gh_mirrors/va/Validation点击查看免费下载相关推荐Respect Validation 之 Cpf 校验器巴西 CPF 号码验证实战与源码原理深度解析Respect Validation 之 Cpf 校验器巴西 CPF 号码验证实战与源码原理深度解析 Cpf 是 Respect\Validation当前仓后端开发工具Validation 库的 Cnpj 验证器巴西 CNPJ 结构校验与校验码算法全解析Validation 库的 Cnpj 验证器巴西 CNPJ 结构校验与校验码算法全解析 本文聚焦 PHP 校验库 Respect Validation htt后端开发工具Respect\\Validation 的 Cnh 校验器巴西驾驶执照CNH号码的完整校验指南Respect\\Validation 的 Cnh 校验器巴西驾驶执照CNH号码的完整校验指南 导读 本文讲解 Respect\\Validation 中后端开发工具上一篇开拓者正义之怒动物伙伴终极培养指南下一篇如何快速上手Mobile Blazor Bindings从安装到第一个原生移动应用的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考