【问题标题】:Convert.FromBase64String does not work in code but works in online toolConvert.FromBase64String 在代码中不起作用,但在在线工具中起作用
【发布时间】:2017-12-05 14:48:48
【问题描述】:

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

“ - W3sic3RhcnRfdGltZSI6IjAiLCJwcm9kdWN0X2lkIjoiODQwMDMzMDQiLCJ1cmwiOiIifSx7InN0YXJ0X3RpbWUiOiI3OSIsInByb2R1Y3RfaWQiOiI4NDAzNjk2MSIsInVybCI6IiJ9LHsic3RhcnRfdGltZSI6IjgyIiwicHJvZHVjdF9pZCI6Ijg0MDAzMDIwIiwidXJsIjoiIn0seyJzdGFydF90aW1lIjoiMTA5IiwicHJvZHVjdF9pZCI6IiIsInVybCI6Imh0dHBzOi8vYmxvZy5sYXJlaW5lZHVzaG9wcGluZy5jYS8yMDE3LzAxL3RyYW5zZm9ybWVyLXNlcy12aWV1eC1nYW50cy1kZS1jdWlyLWVuLTUtbWludXRlcy8ifV0 =” P>

当我将它复制/粘贴到这个在线工具中时它可以工作:https://www.base64decode.org

但是当我使用Convert.FromBase64String(str)时它会抛出异常:

System.FormatException:输入不是有效的 Base-64 字符串,因为它 包含非 base 64 字符、两个以上的填充字符,或 填充字符中的非法字符。

为什么?

【问题讨论】:

  • 去掉“--”
  • 这篇文章可能会回答你的问题。 stackoverflow.com/questions/15114044/…
  • @Darius 不,不是。那是来自标题或其他东西,它不在A-Z0-9 范围内
  • 它们不应该是有效的。它可能适用于 base64decode.org,因为该站点在解码之前将它们删除。可以看到,如果添加或删除更多减号,输出保持不变。

标签: c# base64


【解决方案1】:

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

using System;
using System.Text;

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

【讨论】:

  • Net 使用 base64 变体,其中 - 不是允许的字符。
【解决方案2】:

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

简而言之,.Net 框架使用 Base64 编码的变体,该变体不允许无效字符,而相关站点使用的 PHP 正在使用另一个变体,该变体允许无效字符但会丢弃它们。

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

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

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

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=

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

从零开始升序的base-64位为大写 字符“A”到“Z”,小写字符“a”到“z”, 数字“0”到“9”,符号“+”和“/”。没有价值的 字符“=”用于尾随填充。

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

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

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

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

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

【讨论】:

  • 是的,我花了 3 天的时间终于找到了这个原因,因为我使用 WebUtility.UrlDecode 来包装 base64 图像数据。 (URL 解码将从 base64 字符串中删除 + 使其无效)是正确的,并且必须知道是否发布 base64 数据。
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 2022-08-08
    • 2015-09-03
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    相关资源
    最近更新 更多