如何在解码base64字符串之前添加填充?

4

ColdFusion的binaryDecode(input, 'base64')很挑剔,因为填充是必需的。

如何以=添加填充到一个base64值的正确方式是什么?

1.) Ben Nadel使用

value &= repeatString( "=", ( 4 - ( len( value ) % 4 ) ) );

2.) Arlo Carreon使用

<cfset res = Len(raw_str) % 4>
<cfif res eq 2>
     <cfset raw_str &= "==">
<cfelseif res eq 3>
     <cfset raw_str &= "=">
</cfif>

虽然两种方法看起来都可以工作,但第一种解决方案可能返回1到4个等号,而第二种解决方案可能返回0、1或2个等号。维基百科关于Base64填充的页面表明,一个有效的base64值应该只有1或2个等号。
第一种方法似乎适用于所有的base64值长度,但有时会返回3或4个等号,这有点奇怪。而第二种方法可能会在余数为1的base64值上失败。CF会抛出“输入和输出编码不同”的错误。

为什么需要自己进行填充? - Leigh
@Leigh 在 Json Web Token 中,Base64URL 经常/总是会删除填充。为了将这样的值提供给 binaryDecode(input, 'base64'),必须添加填充。 - Henry
当len(value)%4等于0时,Ben Nadel的算法是否会添加四个等号? - Sinan ILYAS
2个回答

6

填充是规范要求的(RFC 2045、3548/4648)。

除非引用此文档的规范明确说明,否则实现必须在编码数据的末尾包含适当的填充字符。

修复缺少填充的正确方法是附加 = 直到 ( len(value) % 4 ) eq 0。这意味着正确填充的 Base64 字符串只能以以下方式结束:

  • 不带 =
  • = 结束
  • == 结束

规范允许("may")忽略过多的填充。

如果在字符串末尾找到超过允许数量的填充字符(例如,以 "===" 结尾的 base 64 字符串),也可以忽略多余的填充字符。


你所说的 The input and output encodings are not same. 是什么意思?这听起来像一个无效的 Base64 编码字符串。你可能需要检查输入的 toBinary() 返回了什么。它可能会告诉你 函数 ToBinary 的第 1 个参数,现在为 ...,必须是一个 base-64 编码的字符串,这正是问题所在。


len(value) % 4 返回1时,应该是0、1还是2 =?似乎没有任何选项会产生余数为0的值长度。 - Henry
在这种情况下,您的输入不完整。您从哪里/如何获取返回1的输入? - Alex
2
那么在正常情况下 len(value) % 4 不应该返回1吗?谢谢,这就是我需要知道的全部。 - Henry

0
最近我在看这个。
//START SAFE64
// map base64 to a url save chars  https://dev59.com/LnRB5IYBdhLWcg3wLkxM#40415059
const bsCharMap = {
    '+': '-',
    '/': '_',
    '=': '', // note we can safly drop this if we dont care about preseving length
}; // this-sythem-will_gen~~ ;  00~~ 000~ or 0000 dependant on byte length

const sbCharMap = {
    "-": "+"
    ,"_": "/"
}
//construct the regex so the code is defined in one place
const bsRegex = new RegExp(`[${Object.keys(bsCharMap).join()}]`, "g")
const sbRegex = new RegExp(`[${Object.keys(sbCharMap).join()}]`, "g")

function _btos(b64) {
    return  b64.replace(bsRegex, (match) => bsCharMap[match])
}
function _stob(s64) {
    let s = b64.replace(sbRegex, (match) => sbCharMap[match])
    while (s.length%4 !== 0) s += "=";
    return s
}

注意这里_stob正在使用它来根据长度添加填充

也许可以更新https://github.com/syonfox/skid


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接