You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何该Base64字符串可被base64_decode解码却无法被sodium_base642bin处理?

问题:sodium_base642bin解码Base64字符串失败,而base64_decode正常工作

我的代码:

<?php

$a = 'MIIFzzCCBLegAwIBAgIDAfdlMA0GCSqGSIb3DQEBBQUAMHMxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQDDBtDT1BFIFNaQUZJUiAtIEt3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1OiA2MB4XDTExMTEwOTA2MDAwMFoXDTEzMTEwOTA2MDAwMFowgdkxCzAJBgNVBAYTAlBMMRwwGgYDVQQKDBNVcnrEhWQgTWlhc3RhIEdkeW5pMRswGQYDVQQFExJQRVNFTDogNjEwNjA2MDMxMTgxGTAXBgNVBAMMEEplcnp5IFByemV3b3Jza2kxTzBNBgNVBBAwRgwiQWwuIE1hcnN6YcWCa2EgUGnFgnN1ZHNraWVnbyA1Mi81NAwNODEtMzgyIEdkeW5pYQwGUG9sc2thDAlwb21vcnNraWUxDjAMBgNVBCoMBUplcnp5MRMwEQYDVQQEDApQcnpld29yc2tpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMm5vjGqHPthJCMqKpqssSISRos0PYDTcEQzyyurfX67EJWKtZj6HNwuDMEGJ02iBNZfjUl7r8dIi28bSKhNlsfycXZKYRcIjp0+r5RqtR2auo9GQ6veKb61DEAGIqaR+uLLcJVTHCu0w9oXLGbRlGth5eNoj03CxXVAH2IfhbNwIDAQABo4IChzCCAoMwDAYDVR0TAQH/BAIwADCCAUgGA1UdIAEB/wSCATwwggE4MIIBNAYJKoRoAYb3IwEBMIIBJTCB3QYIKwYBBQUHAgIwgdAMgc1EZWtsYXJhY2phIHRhIGplc3Qgb8Wbd2lhZGN6ZW5pZW0gd3lkYXdjeSwgxbxlIHRlbiBjZXJ0eWZpa2F0IHpvc3RhxYIgd3lkYW55IGpha28gY2VydHlmaWthdCBrd2FsaWZpa293YW55IHpnb2RuaWUgeiB3eW1hZ2FuaWFtaSB1c3Rhd3kgbyBwb2RwaXNpZSBlbGVrdHJvbmljem55bSBvcmF6IHRvd2FyenlzesSFY3ltaSBqZWogcm96cG9yesSFZHplbmlhbWkuMEMGCCsGAQUFBwIBFjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6eS9wb2xpdHlrYS5odG1sMAkGA1UdCQQCMAAwIQYDVR0RBBowGIEWai5wcnpld29yc2tpQGdkeW5pYS5wbDAOBgNVHQ8BAf8EBAMCBkAwgZ4GA1UdIwSBljCBk4AU3TGldJXipN4oGS3ZYmnBDMFs8gKhd6R1MHMxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQDDBtDT1BFIFNaQUZJUiAtIEt3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1OiA2ggJb9jBIBgNVHR8EQTA/MD2gO6A5hjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6eS9DUkxfT1pLMzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBYPIqnAreyeql7/opJjcar/qWZy9ruhB2q0lZFsJOhwgMnbQXzp/4vv93YJqcHGAXdHP6EO8FQX47mjo2ZKQmi+cIHJHLONdX/3Im+M17V0iNAh7Z1lOSfTRT+iiwe/F8phcEaD5q2RmvYusR7zXZq/cLL0If0hXoPZ/EHQxjN8pxzxiUx6bJAgturnIMEfRNesxwghdr1dkUjOhGLf3kHVzgM6j3VAM7oFmMUb5y5s96Bzl10DodWitjOEH0vvnIcsppSxH1C1dCAi0o9f/1y2XuLNhBNHMAyTqpYPX8Yvav1c+Z50OMaSXHAnTa20zv8UtiHbaAhwlifCelUMj93S';

echo strlen(base64_decode($a)) . "

";
echo strlen(sodium_base642bin($a, SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING));

base64_decode可以正常解码该字符串,但sodium_base642bin无论使用哪个$id参数(SODIUM_BASE64_VARIANT_ORIGINAL、SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING、SODIUM_BASE64_VARIANT_URLSAFE和SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING)均解码失败,抛出异常:

Fatal error: Uncaught SodiumException: sodium_base642bin(): Argument #1 ($string) must be a valid base64 string


解决思路

核心原因是两个函数的校验严格程度不同:

  • base64_decode是宽松模式:会自动忽略非Base64字符(换行、空格等),对长度不符合4倍数的字符串也会尝试补全解码。
  • sodium_base642bin是严格模式:要求输入完全符合指定Base64变体的规范,包括字符合法性、长度匹配。

1. 清理输入字符串

首先移除所有非目标Base64变体允许的字符:

  • 标准Original变体(+、/、=):保留A-Za-z0-9+/=,过滤其他字符
  • URL-safe变体(-、_):保留A-Za-z0-9-_=,过滤其他字符

示例代码:

// 清理标准Original Base64字符串
$cleaned = preg_replace('/[^A-Za-z0-9+\/=]/', '', $a);

2. 处理Padding与长度规范

Base64编码的长度必须满足:总字符数×6能被8整除(对应原始字节数为整数)。

  • 如果字符串包含=,使用SODIUM_BASE64_VARIANT_ORIGINAL变体
  • 如果无=,先检查长度是否符合规范,若不符合则补=后再用带padding的变体,或直接尝试无padding变体:
$mod = strlen($cleaned) % 4;
if ($mod !== 0) {
    $cleaned .= str_repeat('=', 4 - $mod);
    $decoded = sodium_base642bin($cleaned, SODIUM_BASE64_VARIANT_ORIGINAL);
} else {
    $decoded = sodium_base642bin($cleaned, SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
}

3. 适配URL-safe Base64

如果字符串是URL-safe格式(用-代替+、_代替/),先转换为标准格式再解码:

$urlSafeCleaned = str_replace(['-', '_'], ['+', '/'], $a);
$urlSafeCleaned = preg_replace('/[^A-Za-z0-9+\/=]/', '', $urlSafeCleaned);
$decoded = sodium_base642bin($urlSafeCleaned, SODIUM_BASE64_VARIANT_ORIGINAL);

完整示例

<?php
$a = '你的长字符串';

// 清理标准Original Base64字符
$cleaned = preg_replace('/[^A-Za-z0-9+\/=]/', '', $a);

// 选择对应变体解码
if (str_contains($cleaned, '=')) {
    $decoded = sodium_base642bin($cleaned, SODIUM_BASE64_VARIANT_ORIGINAL);
} else {
    $mod = strlen($cleaned) % 4;
    if ($mod !== 0) {
        $cleaned .= str_repeat('=', 4 - $mod);
        $decoded = sodium_base642bin($cleaned, SODIUM_BASE64_VARIANT_ORIGINAL);
    } else {
        $decoded = sodium_base642bin($cleaned, SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
    }
}

echo strlen($decoded);

内容的提问来源于stack exchange,提问作者neubert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 05:15:26