Convert.FromBase64String 在代码中不起作用,但在在线工具中起作用

Convert.FromBase64String does not work in code but works in online tool

我正在编写一个 C# 应用程序来解码这个字符串:

"--W3sic3RhcnRfdGltZSI6IjAiLCJwcm9kdWN0X2lkIjoiODQwMDMzMDQiLCJ1cmwiOiIifSx7InN0YXJ0X3RpbWUiOiI3OSIsInByb2R1Y3RfaWQiOiI4NDAzNjk2MSIsInVybCI6IiJ9LHsic3RhcnRfdGltZSI6IjgyIiwicHJvZHVjdF9pZCI6Ijg0MDAzMDIwIiwidXJsIjoiIn0seyJzdGFydF90aW1lIjoiMTA5IiwicHJvZHVjdF9pZCI6IiIsInVybCI6Imh0dHBzOi8vYmxvZy5sYXJlaW5lZHVzaG9wcGluZy5jYS8yMDE3LzAxL3RyYW5zZm9ybWVyLXNlcy12aWV1eC1nYW50cy1kZS1jdWlyLWVuLTUtbWludXRlcy8ifV0="

当我 copy/paste 它进入这个在线工具时它起作用了:https://www.base64decode.org

但是当我使用 Convert.FromBase64String(str):

时它会抛出异常

System.FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.

为什么?

您的代码不是有效的 Base64 字符串。字符串开头的 - 字符无效。你可以这样转换。

using System;
using System.Text;

var decodedString = "--W3sic3RhcnRfdGltZSI6IjAiLCJwcm9kdWN0X2lkIjoiODQwMDMzMDQiLCJ1cmwiOiIifSx7InN0YXJ0X3RpbWUiOiI3OSIsInByb2R1Y3RfaWQiOiI4NDAzNjk2MSIsInVybCI6IiJ9LHsic3RhcnRfdGltZSI6IjgyIiwicHJvZHVjdF9pZCI6Ijg0MDAzMDIwIiwidXJsIjoiIn0seyJzdGFydF90aW1lIjoiMTA5IiwicHJvZHVjdF9pZCI6IiIsInVybCI6Imh0dHBzOi8vYmxvZy5sYXJlaW5lZHVzaG9wcGluZy5jYS8yMDE3LzAxL3RyYW5zZm9ybWVyLXNlcy12aWV1eC1nYW50cy1kZS1jdWlyLWVuLTUtbWludXRlcy8ifV0="
    .Replace("-", "");
var bytes = Convert.FromBase64String(decodedString);
var encodedString = Encoding.UTF8.GetString(bytes);
Console.WriteLine(encodedString);

URL 解码将从 base64 字符串中删除 +,使其无效。没有理由因为我指出这一点而对我投反对票。阅读此问题的其他人将使用该代码,但它存在缺陷。如果你解码 'a+==',结果将是字符 'k'。如果您使用 URL 解码来解码 'a+==',则 URL 解码会将字符串转换为 'a ==',您将在尝试解码时遇到异常。

简而言之,.Net Framework 正在使用一种不允许无效字符的 Base64 编码变体,并且 PHP,被相关站点使用,正在使用另一种允许无效字符但允许无效字符的变体丢弃它们。

Base64 编码将三个八位字节转换为四个编码字符。 Base64编码的64个字符的前62个有效字符:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

有几种变体允许字符 62 和 63 使用不同的字符。对于 C#,与最常见的变体一样,完整的字符集是:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=

https://msdn.microsoft.com/en-us/library/dhx0d524(v=vs.110).aspx

The base-64 digits in ascending order from zero are the uppercase characters "A" to "Z", the lowercase characters "a" to "z", the numerals "0" to "9", and the symbols "+" and "/". The valueless character, "=", is used for trailing padding.

已知此变体是 RFC 3548 或 RFC 4648 的标准 'base64' 编码,其中禁止使用无效值,除非另有说明。

PHP 使用 MIME (RFC 2045) 的 Base64 传输编码,允许无效字符但丢弃它们。

在所有其他 Base64 变体中,禁止使用无效字符。

如果原始 Base64 实际上应该包含 - 字符,则它使用了不同的变体。

参见:https://en.wikipedia.org/wiki/Base64#Variants_summary_table

您必须像上面提到的那样从您的字符串中删除 -- 前缀。我想补充一点,当我使用 Convert.FromBase64String(str) 时,我的 base64 字符串中有 data:image/jpeg;base64, 前缀时,我得到了同样的错误。

从字符串中删除 data:image/jpeg;base64, 有效。