usnistgov/oscal-deep-diff

GitHub: usnistgov/oscal-deep-diff

NIST 开发的 OSCAL 文档深度差异比较工具,通过多种匹配算法实现复杂嵌套 JSON 工件的智能化结构化比对。

Stars: 41 | Forks: 11

# OSCAL Deep Diff OSCAL Deep Diff 是一个 CLI 应用程序和库,能够生成与 schema 无关的 JSON 工件比较结果。 此工具的目的是比较 [OSCAL](https://pages.nist.gov/OSCAL/) 工件。 这项工作属于美国国家标准与技术研究院 (NIST) [OSCAL](https://pages.nist.gov/OSCAL/) 计划的一部分。 ## 公共领域 此项目在全球范围内属于 [公共领域](./LICENSE.md)。 如 [CONTRIBUTING.md](./CONTRIBUTING.md) 中所述。 ## 用法 有关端到端的使用示例,请参阅 [`examples/`](./examples/) 目录。 ### CLI 安装 ``` $ npm install -g @oscal/oscal-deep-diff ``` ### 基础比较 OSCAL Deep Diff CLI 需要一个配置文件才能执行比较。 下面提供了一个示例配置文件: ``` leftPath: NIST_SP-800-53_rev5_catalog.json #replace with the JSON documents you want to compare rightPath: NIST_SP-800-53_rev5_catalog.json outputPath: output.json # 这些将在本文档中进一步说明 comparatorConfig: {} outputConfigs: [] ``` 此配置文件指示 deep diff 工具比较两个文档并生成一个输出文件 `output.json`。 示例 OSCAL 工件可以在 [这里](https://github.com/usnistgov/oscal-content) 找到。 要执行比较,请使用以下命令: ``` # 将 "config.yaml" 替换为您在上一步中创建的配置文件 $ oscal-deep-diff --config config.yaml ``` ### 配置 OSCAL deep diff 的比较行为可以进行更改,以适应您比较的需求。 例如,在比较两个文档时,您可能希望忽略部分更改,比如 `id` 字段,因为它们在文档的多次修订中并不稳定。 有时也可能需要忽略某些字段的大小写,或者忽略文档的整个子集。 JSON 文档可能非常复杂,包含对象的嵌套数组。 deep diff 工具可以匹配对象数组,即使它们的顺序被打乱,但这种行为可以受到限制,以适应您比较的需求。 例如,在比较 [OSCAL Catalog](https://pages.nist.gov/OSCAL/concepts/layer/control/catalog) 的两个修订版时,该工具必须正确地将两个文档中的控制项匹配在一起。 这种匹配行为可以通过多种方式更改,例如直接通过 ID 匹配控制项(`AC-1` 始终映射到 `AC-1`,依此类推),或者通过选择产生最少“子更改”的控制项对。 OSCAL Deep Diff 配置的 `comparatorConfig` 字段控制此行为。 #### 结构解析 比较器配置包含一个指向配置对象的 JSON 指针映射。 下面是一个为 [OSCAL Catalog](https://pages.nist.gov/OSCAL/concepts/layer/control/catalog/) 量身定制的比较器配置示例: ``` comparatorConfig: '*': ignoreCase: true 'controls/#': ignore: - controls id: ignoreCase: false priority: 1 /catalog: ignore: - back-matter ``` 在此示例中,比较器将具有以下行为: - `*`:所有字段都将以不区分大小写的方式进行比​​较(支持类 glob 语法)。 - `controls/#`:每个控制项的子控制项(增强项)将被忽略。 - `id`:任何 `id` 字段都将区分大小写进行比较,覆盖 `*` 配置。 - `/catalog`:当比较 `/catalog` 时,忽略 `back-matter` 字段。 请注意,配置映射中的每个项目都告诉比较器**如何比较其 JSON 指针匹配该模式的元素**。 此检查适用于所有 JSON 类型、对象(例如 `/catalog`)、基元(例如 `id`)和数组(例如 `controls`)。 #### 对象配置 - `ignore: string[]`:用于忽略与比较无关的对象属性。 #### 基元配置 - `ignoreCase: boolean`:用于对字符串元素进行不区分大小写的比较。 - `stringComparisonMethod: 'jaro-winkler' | 'cosine' | 'absolute'`:对于字符串元素,此设置控制如何使用 [Jaro-Winkler](https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance)、余弦或绝对编辑距离策略对字符串进行加权。 例如,UUID 应该始终进行绝对比较,但在某些情况下,彼此相似的属性中也存在一定意义。 #### 数组配置 - `matcherGenerators: []`:数组比较是一个难以解决的问题,因为匹配是一项开销很大的操作。 OSCAL Deep Diff 通过匹配最小化子更改数量的数组元素来比较数组。 这种匹配可以通过几种方式完成,这些方式各有利弊。 `matcherGenerator` 允许您指定比较数组的方式。 以下是可用的匹配器生成器类型: - `ObjectPropertyMatcherContainer`:此算法仅通过对象属性来匹配数组项。 例如,可以将比较配置为通过查找具有相同 `id` 属性的对象来匹配对象数组。 此算法产生结果最快,但要求用户根据其正在比较的文档的属性来调整比较。 示例: matcherGenerators: - type: ObjectPropertyMatcherContainer property: id - `OptimalMatcherContainer`:此算法查找给定对象数组包含的属性,然后使用与 `ObjectPropertyMatcherContainer` 相同的逻辑尝试通过每个属性匹配对象。 产生最少更改数量的属性将被选中。 此容器没有配置选项。 示例: matcherGenerators: - type: OptimalMacherContainer - `HungarianMatcherContainer`:[匈牙利算法](https://en.wikipedia.org/wiki/Hungarian_algorithm) 是一种可用于将项目匹配在一起的算法。 选择此匹配器时,将使用以下方法将数组项匹配在一起: 1. 比较数组项的每种可能组合,生成可能组合及其相关分数的邻接矩阵。 2. 使用代表未匹配元素的附加项扩充邻接矩阵(允许将项目标记为已添加或已删除)。 3. 在邻接矩阵上调用匈牙利算法的实现,生成一个配对数组。 此算法在空间和时间上开销最大。 它也是在无需任何调整的情况下最有可能产生良好结果的选项。 示例: matcherGenerators: - type: HungarianMatcherContainer - `outOfTreeEnabled: boolean`:启用时,可以进行跨树比较。 此选项在处理嵌套的对象数组时很有用,因为对象可能会从一个子数组移动到另一个子数组。 一个很好的例子是 [OSCAL Catalog](https://pages.nist.gov/OSCAL/concepts/layer/control/catalog/) 模型,它具有被组织成组的控制项。 如果在 `control` 上将 `outOfTreeEnabled` 设置为 true,比较器将检查在组之间移动的控制项。 #### 其他配置 - `priority: number`:如果两个指针匹配,则使用优先级来决定应用哪个设置。优先级越高,意味着重叠的设置将优先。 ### 输出 进行比较后,输出仅为一个 JSON 文档。 比较文档的根包含 3 个属性:`leftDocument`、`rightDocument` 和 `changes`。 左右文档指的是指定的文档路径。 将 `oscal-deep-diff` 用作库时,这些是手动设置的,并且可以指向 URL。`changes` 属性包含比较器找到的更改列表。 更改类型包括: - `property_changed`:该属性在两个文档中都存在,但已更改。 - `property_added`:该属性仅存在于右侧文档中。 - `property_deleted`:该属性仅存在于左侧文档中。 - `array_changed`:项数组已更改。此更改类型更复杂,其中包含仅存在于右侧文档中的数组项、仅存在于左侧文档中的数组项,以及存在于两个文档中但子文档中存在差异的数组项。 ### 替代输出 比较的 `outputConfigs` 属性用于将原始输出转换为更易于理解的文档。 例如,随着控制项数量的增加,对两个 [OSCAL Catalogs](https://pages.nist.gov/OSCAL/concepts/layer/control/catalog/) 的比较通常变得非常难以处理。 原始输出可以转换为 Excel 文档,该文档会收集所有控制项级别的更改。 ``` outputConfigs: - selection: controls identifiers: - 'id' - 'title' outputType: excel outputPath: output.xlsx ``` ## 引用 此项目有一个相关的 [DOI](https://www.doi.org/) 条目:[`doi:10.18434/mds2-2727`](https://data.nist.gov/od/id/mds2-2727)。
标签:JSON, MITM代理, OSCAL, 合规管理, 差异比较, 文档结构分析, 暗色界面, 自动化攻击