Skip to main content

10. Test Vectors (测试向量)

以下是用于验证Base编码实现正确性的标准测试向量。


Base64测试向量

BASE64("") = ""

BASE64("f") = "Zg=="

BASE64("fo") = "Zm8="

BASE64("foo") = "Zm9v"

BASE64("foob") = "Zm9vYg=="

BASE64("fooba") = "Zm9vYmE="

BASE64("foobar") = "Zm9vYmFy"

验证表

输入输出长度填充
""""0
"f""Zg=="42个=
"fo""Zm8="41个=
"foo""Zm9v"4
"foob""Zm9vYg=="82个=
"fooba""Zm9vYmE="81个=
"foobar""Zm9vYmFy"8

Base32测试向量

BASE32("") = ""

BASE32("f") = "MY======"

BASE32("fo") = "MZXQ===="

BASE32("foo") = "MZXW6==="

BASE32("foob") = "MZXW6YQ="

BASE32("fooba") = "MZXW6YTB"

BASE32("foobar") = "MZXW6YTBOI======"

验证表

输入输出长度填充
""""0
"f""MY======"86个=
"fo""MZXQ===="84个=
"foo""MZXW6==="83个=
"foob""MZXW6YQ="81个=
"fooba""MZXW6YTB"8
"foobar""MZXW6YTBOI======"166个=

Base32Hex测试向量

BASE32-HEX("") = ""

BASE32-HEX("f") = "CO======"

BASE32-HEX("fo") = "CPNG===="

BASE32-HEX("foo") = "CPNMU==="

BASE32-HEX("foob") = "CPNMUOG="

BASE32-HEX("fooba") = "CPNMUOJ1"

BASE32-HEX("foobar") = "CPNMUOJ1E8======"

验证表

输入输出长度填充
""""0
"f""CO======"86个=
"fo""CPNG===="84个=
"foo""CPNMU==="83个=
"foob""CPNMUOG="81个=
"fooba""CPNMUOJ1"8
"foobar""CPNMUOJ1E8======"166个=

Base16测试向量

BASE16("") = ""

BASE16("f") = "66"

BASE16("fo") = "666F"

BASE16("foo") = "666F6F"

BASE16("foob") = "666F6F62"

BASE16("fooba") = "666F6F6261"

BASE16("foobar") = "666F6F626172"

验证表

输入输出长度说明
""""0空输入
"f""66"21字节→2字符
"fo""666F"42字节→4字符
"foo""666F6F"63字节→6字符
"foob""666F6F62"84字节→8字符
"fooba""666F6F6261"105字节→10字符
"foobar""666F6F626172"126字节→12字符

扩展测试向量

特殊字符

输入: "\n" (换行符, 0x0A)
Base64: "Cg=="
Base32: "BI======"
Base16: "0A"

输入: "\r\n" (CRLF, 0x0D 0x0A)
Base64: "DQo="
Base32: "BUQQ===="
Base16: "0D0A"

输入: "\0" (空字节, 0x00)
Base64: "AA=="
Base32: "AA======"
Base16: "00"

二进制数据

输入: [0x00, 0x01, 0x02]
Base64: "AAEC"
Base32: "AAAQE==="
Base16: "000102"

输入: [0xFF, 0xFE, 0xFD]
Base64: "///9"
Base32: "777736==="
Base16: "FFFEFD"

输入: [0xDE, 0xAD, 0xBE, 0xEF]
Base64: "3q2+7w=="
Base32: "32W353Y="
Base16: "DEADBEEF"

UTF-8文本

输入: "€" (欧元符号, 0xE2 0x82 0xAC)
Base64: "4oKs"
Base32: "4KBKY==="
Base16: "E282AC"

输入: "你好" (中文, UTF-8编码)
Base64: "5L2g5aW9"
Base32: "6SXG6WVM6===="
Base16: "E4BDA0E5A5BD"

使用测试向量

单元测试示例(Python)

import base64

def test_base64():
"""Base64测试向量验证"""
vectors = [
("", ""),
("f", "Zg=="),
("fo", "Zm8="),
("foo", "Zm9v"),
("foob", "Zm9vYg=="),
("fooba", "Zm9vYmE="),
("foobar", "Zm9vYmFy"),
]

for input_str, expected in vectors:
result = base64.b64encode(input_str.encode()).decode()
assert result == expected, f"Failed: {input_str}"
print(f"✓ BASE64('{input_str}') = '{result}'")

def test_base32():
"""Base32测试向量验证"""
vectors = [
("", ""),
("f", "MY======"),
("fo", "MZXQ===="),
("foo", "MZXW6==="),
("foob", "MZXW6YQ="),
("fooba", "MZXW6YTB"),
("foobar", "MZXW6YTBOI======"),
]

for input_str, expected in vectors:
result = base64.b32encode(input_str.encode()).decode()
assert result == expected, f"Failed: {input_str}"
print(f"✓ BASE32('{input_str}') = '{result}'")

def test_base16():
"""Base16测试向量验证"""
vectors = [
("", ""),
("f", "66"),
("fo", "666F"),
("foo", "666F6F"),
("foob", "666F6F62"),
("fooba", "666F6F6261"),
("foobar", "666F6F626172"),
]

for input_str, expected in vectors:
result = base64.b16encode(input_str.encode()).decode()
assert result == expected, f"Failed: {input_str}"
print(f"✓ BASE16('{input_str}') = '{result}'")

Go测试示例

func TestBase64(t *testing.T) {
vectors := []struct{
input string
expected string
}{
{"", ""},
{"f", "Zg=="},
{"fo", "Zm8="},
{"foo", "Zm9v"},
{"foob", "Zm9vYg=="},
{"fooba", "Zm9vYmE="},
{"foobar", "Zm9vYmFy"},
}

for _, v := range vectors {
result := base64.StdEncoding.EncodeToString([]byte(v.input))
if result != v.expected {
t.Errorf("BASE64(%q) = %q, want %q", v.input, result, v.expected)
}
}
}

互操作性测试

跨平台验证

# 使用openssl验证Base64
echo -n "foobar" | openssl base64
# 应输出: Zm9vYmFy

# 使用Python验证
python3 -c "import base64; print(base64.b64encode(b'foobar').decode())"
# 应输出: Zm9vYmFy

# 使用Node.js验证
node -e "console.log(Buffer.from('foobar').toString('base64'))"
# 应输出: Zm9vYmFy

解码验证

# Base64解码
echo "Zm9vYmFy" | base64 -d
# 应输出: foobar

# Base32解码
echo "MZXW6YTBOI======" | base32 -d
# 应输出: foobar

# Base16解码
echo "666F6F626172" | xxd -r -p
# 应输出: foobar

边界测试用例

最小输入

输入: 单字节
"A" (0x41)

Base64: "QQ=="
Base32: "IE======"
Base16: "41"

最大单组输入

Base64 (3字节):
"ABC" (0x41 0x42 0x43)
Base64: "QUJD"

Base32 (5字节):
"ABCDE" (0x41 0x42 0x43 0x44 0x45)
Base32: "IFBEGRCF"

全零和全一

输入: [0x00, 0x00, 0x00]
Base64: "AAAA"
Base32: "AAAAAAAA"
Base16: "000000"

输入: [0xFF, 0xFF, 0xFF]
Base64: "////"
Base32: "77777777"
Base16: "FFFFFF"

回归测试建议

必测用例

✅ 空输入
✅ 标准测试向量(上述所有)
✅ 填充边界(1, 2字节输入)
✅ 大数据(>1MB)
✅ 随机二进制数据
✅ 特殊字符(NUL, 换行等)
✅ UTF-8多字节字符
✅ 大小写处理(Base32/16)

错误测试

❌ 非法字符
❌ 错误的填充
❌ 截断的输入
❌ 超长输入
❌ 格式错误

性能基准

建议使用这些测试向量进行性能测试:

1. 小数据: "foobar" (6字节)
- 测试函数调用开销

2. 中数据: 1KB随机数据
- 测试常规性能

3. 大数据: 1MB随机数据
- 测试批量处理效率

这些测试向量是RFC 4648规范的一部分,所有符合规范的实现都应通过这些测试。建议在实现Base编码时,首先使用这些标准测试向量验证正确性,然后再进行扩展测试。