CPE匹配
本示例演示如何使用CPE库进行基本的CPE匹配操作,包括精确匹配、模式匹配和批量匹配。
概述
CPE匹配是识别和比较软件组件的核心功能。本示例展示了各种匹配技术,从简单的字符串比较到复杂的模式匹配。
完整示例
go
package main
import (
"fmt"
"log"
"github.com/scagogogo/cpe"
)
func main() {
fmt.Println("=== CPE匹配示例 ===")
// 示例1:基本匹配
fmt.Println("\n1. 基本匹配:")
// 创建测试CPE
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe3, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:11:*:*:*:*:*:*:*")
fmt.Printf("CPE1: %s\n", cpe1.GetURI())
fmt.Printf("CPE2: %s\n", cpe2.GetURI())
fmt.Printf("CPE3: %s\n", cpe3.GetURI())
// 精确匹配
fmt.Printf("CPE1 == CPE2: %t\n", cpe1.Match(cpe2))
fmt.Printf("CPE1 == CPE3: %t\n", cpe1.Match(cpe3))
// 示例2:通配符匹配
fmt.Println("\n2. 通配符匹配:")
// 创建通配符模式
pattern, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:*:*:*:*:*:*:*:*:*")
testCPEs := []string{
"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*",
"cpe:2.3:a:microsoft:office:2019:*:*:*:*:*:*:*",
"cpe:2.3:a:apache:tomcat:9.0.0:*:*:*:*:*:*:*",
"cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*",
}
fmt.Printf("匹配模式: %s\n", pattern.GetURI())
fmt.Println("匹配结果:")
for i, cpeStr := range testCPEs {
testCPE, _ := cpe.ParseCpe23(cpeStr)
match := pattern.Match(testCPE)
status := "❌"
if match {
status = "✅"
}
fmt.Printf(" %s %d. %s %s\n", status, i+1, testCPE.Vendor, testCPE.ProductName)
}
// 示例3:版本范围匹配
fmt.Println("\n3. 版本范围匹配:")
// 定义版本范围
baseProduct := "cpe:2.3:a:apache:tomcat"
versions := []string{"8.5.0", "9.0.0", "9.0.1", "9.1.0", "10.0.0"}
// 目标版本范围:9.x系列
targetPattern := "9.*"
fmt.Printf("匹配Tomcat %s版本:\n", targetPattern)
for _, version := range versions {
cpeStr := fmt.Sprintf("%s:%s:*:*:*:*:*:*:*", baseProduct, version)
testCPE, _ := cpe.ParseCpe23(cpeStr)
// 简单的版本模式匹配
match := cpe.MatchVersionPattern(testCPE.Version, targetPattern)
status := "❌"
if match {
status = "✅"
}
fmt.Printf(" %s Tomcat %s\n", status, version)
}
// 示例4:组件类型匹配
fmt.Println("\n4. 组件类型匹配:")
mixedCPEs := []string{
"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*", // 应用程序
"cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*", // 操作系统
"cpe:2.3:h:cisco:catalyst_2960:*:*:*:*:*:*:*:*", // 硬件
"cpe:2.3:a:apache:tomcat:9.0.0:*:*:*:*:*:*:*", // 应用程序
}
// 只匹配应用程序
fmt.Println("应用程序组件:")
for i, cpeStr := range mixedCPEs {
testCPE, _ := cpe.ParseCpe23(cpeStr)
if testCPE.Part.ShortName == "a" {
fmt.Printf(" ✅ %d. %s %s\n", i+1, testCPE.Vendor, testCPE.ProductName)
} else {
fmt.Printf(" ❌ %d. %s %s (%s)\n", i+1, testCPE.Vendor, testCPE.ProductName, testCPE.Part.LongName)
}
}
// 示例5:供应商匹配
fmt.Println("\n5. 供应商匹配:")
vendors := []string{"microsoft", "apache", "oracle", "cisco"}
for _, vendor := range vendors {
fmt.Printf("\n%s 产品:\n", vendor)
for i, cpeStr := range mixedCPEs {
testCPE, _ := cpe.ParseCpe23(cpeStr)
if testCPE.Vendor == vendor {
fmt.Printf(" ✅ %d. %s (%s)\n", i+1, testCPE.ProductName, testCPE.Part.LongName)
}
}
}
// 示例6:批量匹配
fmt.Println("\n6. 批量匹配:")
// 创建CPE列表
cpeList := []*cpe.CPE{}
for _, cpeStr := range mixedCPEs {
testCPE, _ := cpe.ParseCpe23(cpeStr)
cpeList = append(cpeList, testCPE)
}
// 定义匹配条件
matchConditions := []struct {
name string
condition func(*cpe.CPE) bool
}{
{
"Microsoft产品",
func(c *cpe.CPE) bool { return c.Vendor == "microsoft" },
},
{
"应用程序",
func(c *cpe.CPE) bool { return c.Part.ShortName == "a" },
},
{
"版本10",
func(c *cpe.CPE) bool { return c.Version == "10" },
},
{
"网络设备",
func(c *cpe.CPE) bool { return c.Part.ShortName == "h" },
},
}
for _, condition := range matchConditions {
fmt.Printf("\n匹配条件: %s\n", condition.name)
matchCount := 0
for i, testCPE := range cpeList {
if condition.condition(testCPE) {
fmt.Printf(" ✅ %d. %s %s %s\n", i+1, testCPE.Vendor, testCPE.ProductName, testCPE.Version)
matchCount++
}
}
fmt.Printf(" 匹配数量: %d/%d\n", matchCount, len(cpeList))
}
// 示例7:复合匹配条件
fmt.Println("\n7. 复合匹配条件:")
// 复合条件:Microsoft的应用程序
fmt.Println("Microsoft应用程序:")
for i, testCPE := range cpeList {
if testCPE.Vendor == "microsoft" && testCPE.Part.ShortName == "a" {
fmt.Printf(" ✅ %d. %s %s\n", i+1, testCPE.ProductName, testCPE.Version)
}
}
// 示例8:模糊匹配
fmt.Println("\n8. 模糊匹配:")
// 模糊匹配示例(产品名称相似性)
targetProduct := "windows"
similarProducts := []string{"windows", "win", "microsoft_windows", "windows_server"}
fmt.Printf("与'%s'相似的产品:\n", targetProduct)
for _, product := range similarProducts {
// 简单的相似度计算(包含关系)
similarity := 0.0
if product == targetProduct {
similarity = 1.0
} else if len(product) > 0 && len(targetProduct) > 0 {
if product == "win" && targetProduct == "windows" {
similarity = 0.7 // 缩写匹配
} else if (product == "microsoft_windows" || product == "windows_server") && targetProduct == "windows" {
similarity = 0.8 // 包含匹配
}
}
status := "❌"
if similarity >= 0.7 {
status = "✅"
}
fmt.Printf(" %s %s (相似度: %.1f)\n", status, product, similarity)
}
// 示例9:匹配统计
fmt.Println("\n9. 匹配统计:")
stats := map[string]int{
"总CPE数量": len(cpeList),
"应用程序": 0,
"操作系统": 0,
"硬件设备": 0,
"Microsoft": 0,
"Apache": 0,
"其他供应商": 0,
}
for _, testCPE := range cpeList {
switch testCPE.Part.ShortName {
case "a":
stats["应用程序"]++
case "o":
stats["操作系统"]++
case "h":
stats["硬件设备"]++
}
switch testCPE.Vendor {
case "microsoft":
stats["Microsoft"]++
case "apache":
stats["Apache"]++
default:
stats["其他供应商"]++
}
}
fmt.Println("匹配统计结果:")
for category, count := range stats {
fmt.Printf(" %s: %d\n", category, count)
}
}
预期输出
=== CPE匹配示例 ===
1. 基本匹配:
CPE1: cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*
CPE2: cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*
CPE3: cpe:2.3:a:microsoft:windows:11:*:*:*:*:*:*:*
CPE1 == CPE2: true
CPE1 == CPE3: false
2. 通配符匹配:
匹配模式: cpe:2.3:a:microsoft:*:*:*:*:*:*:*:*:*
匹配结果:
✅ 1. microsoft windows
✅ 2. microsoft office
❌ 3. apache tomcat
❌ 4. microsoft windows
3. 版本范围匹配:
匹配Tomcat 9.*版本:
❌ Tomcat 8.5.0
✅ Tomcat 9.0.0
✅ Tomcat 9.0.1
✅ Tomcat 9.1.0
❌ Tomcat 10.0.0
4. 组件类型匹配:
应用程序组件:
✅ 1. microsoft windows
❌ 2. microsoft windows (Operating System)
❌ 3. cisco catalyst_2960 (Hardware)
✅ 4. apache tomcat
5. 供应商匹配:
microsoft 产品:
✅ 1. windows (Application)
✅ 2. windows (Operating System)
apache 产品:
✅ 4. tomcat (Application)
cisco 产品:
✅ 3. catalyst_2960 (Hardware)
6. 批量匹配:
匹配条件: Microsoft产品
✅ 1. microsoft windows 10
✅ 2. microsoft windows 10
匹配数量: 2/4
匹配条件: 应用程序
✅ 1. microsoft windows 10
✅ 4. apache tomcat 9.0.0
匹配数量: 2/4
匹配条件: 版本10
✅ 1. microsoft windows 10
✅ 2. microsoft windows 10
匹配数量: 2/4
匹配条件: 网络设备
✅ 3. cisco catalyst_2960 *
匹配数量: 1/4
7. 复合匹配条件:
Microsoft应用程序:
✅ 1. windows 10
8. 模糊匹配:
与'windows'相似的产品:
✅ windows (相似度: 1.0)
✅ win (相似度: 0.7)
✅ microsoft_windows (相似度: 0.8)
✅ windows_server (相似度: 0.8)
9. 匹配统计:
匹配统计结果:
总CPE数量: 4
应用程序: 2
操作系统: 1
硬件设备: 1
Microsoft: 2
Apache: 1
其他供应商: 1
关键概念
1. 匹配类型
- 精确匹配: 所有字段完全相同
- 通配符匹配: 使用
*
匹配任意值 - 模式匹配: 使用正则表达式或模式
- 范围匹配: 版本或数值范围匹配
2. 匹配策略
- 字段级匹配: 逐个字段比较
- 语义匹配: 理解同义词和缩写
- 模糊匹配: 基于相似度的匹配
- 结构化匹配: 考虑CPE层次结构
3. 性能考虑
- 索引优化: 为频繁查询的字段建立索引
- 批量处理: 一次处理多个匹配操作
- 缓存结果: 缓存常用的匹配结果
- 早期终止: 在确定不匹配时提前退出
最佳实践
- 选择合适的匹配类型: 根据需求选择精确匹配或模糊匹配
- 使用通配符: 合理使用通配符提高匹配灵活性
- 验证输入: 在匹配前验证CPE格式的正确性
- 处理边界情况: 考虑空值、特殊字符等情况
- 性能监控: 监控匹配操作的性能表现