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==" | 4 | 2个= |
"fo" | "Zm8=" | 4 | 1个= |
"foo" | "Zm9v" | 4 | 无 |
"foob" | "Zm9vYg==" | 8 | 2个= |
"fooba" | "Zm9vYmE=" | 8 | 1个= |
"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======" | 8 | 6个= |
"fo" | "MZXQ====" | 8 | 4个= |
"foo" | "MZXW6===" | 8 | 3个= |
"foob" | "MZXW6YQ=" | 8 | 1个= |
"fooba" | "MZXW6YTB" | 8 | 无 |
"foobar" | "MZXW6YTBOI======" | 16 | 6个= |
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======" | 8 | 6个= |
"fo" | "CPNG====" | 8 | 4个= |
"foo" | "CPNMU===" | 8 | 3个= |
"foob" | "CPNMUOG=" | 8 | 1个= |
"fooba" | "CPNMUOJ1" | 8 | 无 |
"foobar" | "CPNMUOJ1E8======" | 16 | 6个= |
Base16测试向量
BASE16("") = ""
BASE16("f") = "66"
BASE16("fo") = "666F"
BASE16("foo") = "666F6F"
BASE16("foob") = "666F6F62"
BASE16("fooba") = "666F6F6261"
BASE16("foobar") = "666F6F626172"
验证表
| 输入 | 输出 | 长度 | 说明 |
|---|---|---|---|
"" | "" | 0 | 空输入 |
"f" | "66" | 2 | 1字节→2字符 |
"fo" | "666F" | 4 | 2字节→4字符 |
"foo" | "666F6F" | 6 | 3字节→6字符 |
"foob" | "666F6F62" | 8 | 4字节→8字符 |
"fooba" | "666F6F6261" | 10 | 5字节→10字符 |
"foobar" | "666F6F626172" | 12 | 6字节→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编码时,首先使用这些标准测试向量验证正确性,然后再进行扩展测试。