如何从零开始计算CID?如何在Go中生成合法测试用假CID?
CID相关问题解答
1. 从零开始计算CID
CID(内容标识符)的计算逻辑分版本,核心是基于内容哈希+结构化前缀编码:
CIDv0
v0是简化版本,仅支持SHA-256哈希,步骤如下:
- 对目标内容计算SHA-256哈希(32字节)
- 给哈希添加multihash前缀:
0x12(SHA-256的multicodec标识) +0x20(哈希长度32字节) - 将拼接后的字节序列做Base58编码,得到以
Qm开头的v0 CID
CIDv1
v1支持多种哈希算法和内容类型,结构更灵活,步骤如下:
- 确定版本标识:固定为1字节
0x01 - 确定内容类型(Codec):将内容类型(如
raw、dag-pb)转换为对应的varint编码(比如raw对应0x55,dag-pb对应0x70) - 生成multihash:
- 选择哈希算法,获取对应的multicodec标识(如SHA-256是
0x12,Blake2b-256是0xb220) - 对内容计算该算法的哈希,获取哈希字节
- 拼接前缀:
算法标识+哈希长度字节+哈希值,得到完整multihash
- 选择哈希算法,获取对应的multicodec标识(如SHA-256是
- 拼接CID原始字节:
版本字节+Codec varint+multihash - 将拼接后的字节做Base32编码(默认无填充、小写),得到以
baf开头的v1 CID
2. Go语言生成形式合法的假CID函数
以下函数可生成格式完全合法的假CID,无需真实计算内容哈希,支持指定输入字节、内容类型和CID版本:
import ( "crypto/rand" "fmt" "github.com/multiformats/go-base32" "github.com/multiformats/go-base58" "github.com/multiformats/go-multicodec" "github.com/multiformats/go-varint" ) // GenerateFakeCID 生成格式合法的假CID // data: 可选输入字节序列,用于生成假哈希(留空则用随机字节) // codecStr: 内容类型字符串,如"raw"、"dag-pb" // version: CID版本,仅支持0或1 func GenerateFakeCID(data []byte, codecStr string, version int) (string, error) { switch version { case 0: // v0仅支持SHA-256哈希,构造32字节假哈希 fakeHash := make([]byte, 32) if len(data) > 0 { copy(fakeHash, data) } else { if _, err := rand.Read(fakeHash); err != nil { return "", err } } // 拼接multihash前缀并Base58编码 multihash := append([]byte{0x12, 0x20}, fakeHash...) return base58.Encode(multihash), nil case 1: // 解析内容类型对应的multicodec codec, err := multicodec.StringToCode(codecStr) if err != nil { return "", fmt.Errorf("invalid codec: %w", err) } // 将codec编码为varint codecBuf := make([]byte, 8) codecLen := varint.PutUvarint(codecBuf, uint64(codec)) codecVarint := codecBuf[:codecLen] // 生成SHA-256格式的假multihash(可扩展支持其他算法) fakeHash := make([]byte, 32) if len(data) > 0 { copy(fakeHash, data) } else { if _, err := rand.Read(fakeHash); err != nil { return "", err } } multihash := append([]byte{0x12, 0x20}, fakeHash...) // 拼接完整CID字节并Base32编码 cidBytes := append([]byte{0x01}, codecVarint...) cidBytes = append(cidBytes, multihash...) return base32.RawStdEncoding.EncodeToString(cidBytes), nil default: return "", fmt.Errorf("unsupported version: %d", version) } }
函数说明
- CIDv0:严格遵循v0格式,生成
Qm开头的合法字符串,假哈希可基于输入字节或随机生成 - CIDv1:支持指定内容类型,自动处理varint编码,生成
baf开头的合法字符串,同样支持输入字节或随机假哈希 - 生成的假CID可通过CID校验工具验证格式合法性,适合测试场景使用
内容的提问来源于stack exchange,提问作者Cutaraca
相关产品推荐
相关产品推荐

