🎲 生成随机 CVSS 向量作为测试数据
问题
你需要 CVSS 向量来填充测试数据库、写属性测试或给仪表盘做演示——但手写合法向量又枯燥、又偏向几个熟悉的套路。
方案
流程如下:
CLI:random
cvss random 输出一个合法的、仅含基础指标的 v3.1 向量,各指标值均匀随机:
bash
cvss randomtext
CVSS:3.1/AV:A/AC:L/PR:H/UI:R/S:C/C:N/I:L/A:H每次调用都不同。常用 flag:
bash
cvss random --score # 附带算好的分数
cvss random --temporal # 加 E/RL/RC
cvss random --full # 加时间 + 环境指标
cvss random --cvss-version 3.0 # 用 v3.0 而非 v3.1
cvss random --format json # {"vector": "..."}bash
cvss random --scoretext
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N
Score: 7.1 (High)bash
cvss random --temporaltext
CVSS:3.1/AV:A/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L/E:H/RL:T/RC:Rbash
cvss random --format jsonjson
{
"vector": "CVSS:3.1/AV:L/AC:H/PR:H/UI:R/S:C/C:H/I:N/A:H"
}循环生成一批:
bash
for i in $(seq 1 5); do cvss random; done > fixtures.txtGo SDK:mock.RandomCvss3xFull
pkg/mock 包直接给你对象,省去把字符串再 parse 回来。RandomCvss3x 只有基础指标,RandomCvss3xWithTemporal 加 E/RL/RC,RandomCvss3xFull 加全部 11 个环境指标。参数是次版本号(0 或 1)。
go
package main
import (
"fmt"
"github.com/scagogogo/cvss-skills/pkg/mock"
)
func main() {
// 仅基础指标的 v3.1。
fmt.Println(mock.RandomCvss3x(1).String())
// 全量(时间 + 环境)v3.1。
full := mock.RandomCvss3xFull(1)
fmt.Println(full.String())
// 带分数。
cv, score, err := mock.RandomCvss3xWithScore(1)
if err != nil {
panic(err)
}
fmt.Printf("%s -> %.1f\n", cv.String(), score)
// v3.0 随机向量串。
fmt.Println(mock.RandomCvss3xVectorString(0))
}某次运行的输出:
text
CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:N/I:H/A:L
CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:N/I:H/A:L/E:X/RL:W/RC:R/CR:L/IR:L/AR:M/MAV:X/MAC:H/MPR:H/MUI:N/MS:C/MC:X/MI:H/MA:L
CVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:U/C:L/I:H/A:N -> 5.3
CVSS:3.0/AV:P/AC:H/PR:H/UI:N/S:C/C:N/I:L/A:N可复现的随机性
pkg/mock 用 math/rand 且未播种。要确定性的测试夹具,在测试开头播种全局源(rand.Seed(42)),或者一次性把生成的字符串固化到 golden 文件里再提交。
讨论
- 每个生成的向量都合法、可评分。
RandomCvss3xFull把每个指标都设成合法值,所以NewCalculator(cv).Calculate()不会报错。 - 分布是按指标均匀,不是按分数均匀。 每个指标独立选取,所以分数分布不是均匀的——极端分(0.0、10.0)比中段分更少见。如果你要特定严重性的向量,用
build构造,或用 preset。 --full可能含X(Not Defined)。 环境指标会包含X值,calculator 把它当“继承基础指标”——所以全量随机向量仍能合理评分。- 不是你想要的? 要固定严重性的向量,用
preset命令,或 Go 里的cvss.CriticalV31()/HighV31()/MediumV31()/LowV31()/NoneV31()。