【问题标题】:Base64 String throwing invalid character errorBase64 字符串抛出无效字符错误
【发布时间】:2009-04-02 17:51:05
【问题描述】:

我不断收到 Base64 无效字符错误,即使我不应该这样做。

程序获取一个 XML 文件并将其导出为文档。如果用户需要,它也会压缩文件。压缩工作正常并返回一个 Base64 字符串,该字符串编码为 UTF-8 并写入文件。

当需要将文档重新加载到程序中时,我必须检查它是否被压缩,代码很简单:

byte[] gzBuffer = System.Convert.FromBase64String(text);
return "1F-8B-08" == BitConverter.ToString(new List<Byte>(gzBuffer).GetRange(4, 3).ToArray());

它检查字符串的开头是否有 GZips 代码。

现在问题是,我的所有测试都有效。我取一个字符串,对其进行压缩、解压缩,然后将其与原始字符串进行比较。问题是当我得到从 ADO 记录集返回的字符串时。该字符串正是写入文件的内容(最后添加了“\ 0”,但我认为它甚至不会做任何事情,即使修剪掉它仍然会抛出)。我什至将整个字符串复制并粘贴到测试方法中并压缩/解压缩。工作正常。

测试会通过,但使用完全相同的字符串代码会失败?唯一的区别是,我不是仅仅声明一个常规字符串并将其传递给我,而是从记录集中返回一个。

关于我做错了什么有什么想法吗?

【问题讨论】:

  • 如果您发布一个您传递给 Convert.FromBase64String 的字符串示例,这可能会有所帮助(例如,如果您在调用之前直接放置一个 Debug.Write,您会得到什么输出)
  • ...即使您发布了第一个和最后 8 个字节左右以及字符串长度,也可能足以看出该字符串是正确的格式。
  • qGcAAB+LCA ... cAAA== 它的 2376 个字符长。
  • 您是否仍然收到 FormatException:Invalid Characters,还是其他异常?
  • ...我想你一定知道问题出在哪里了?

标签: c# string ado.net base64 invalid-characters


【解决方案1】:

你说

字符串正是所写的 到文件中(添加了一个 最后是“\ 0”,但我不认为 甚至可以做任何事情)。

事实上,它确实做了一些事情(它会导致您的代码抛出 FormatException:"Invalid character in a Base-64 string"),因为 Convert.FromBase64String 不认为 "\0" 是有效的 Base64字符。

  byte[] data1 = Convert.FromBase64String("AAAA\0"); // Throws exception
  byte[] data2 = Convert.FromBase64String("AAAA");   // Works

解决方案:摆脱零终止。(可以致电.Trim("\0")

注意事项

MSDN docs for Convert.FromBase64String 说它会抛出一个FormatException

s的长度,忽略空格 字符,不是零或倍数 4 个。

-或-

s 的格式无效。 s 包含非基数 64 字符,更多 超过两个填充字符,或 之间的非空白字符 填充字符。

还有那个

以升序排列的基数 64 位 从零开始是大写字符 'A' 到 'Z',小写字符 'a' 到“z”,数字“0”到“9”,以及 符号“+”和“/”。

【讨论】:

  • 我把 \0 剪掉了,它仍然会抛出。
  • 它仍然会抛出 FormatException,还是其他什么?传递给 FromBase64String 的确切字符串是什么?
  • 确切的字符串有点长。有我不知道的尺寸限制吗?但是有什么是有效的,我检查了它是否存在 Base64 中不允许的任何字符。也许我只是修剪错了,虽然它没有解释为什么测试运行良好。
  • @Brandon:长度是 4 的倍数吗?老实说,即使您发布了第一个和最后 8 个字节以及字符串长度,也可能足以看出该字符串是正确的格式。
  • 它是 4 的倍数,我假设字符串末尾的 ==(请参阅我对原始帖子的回复)只是为了填充目的?
【解决方案2】:

是否允许空字符实际上取决于所讨论的 base64 编解码器。 鉴于 Base64 标准的模糊性(没有权威的确切规范),许多实现会忽略它作为空白。然后其他人可以将其标记为问题。最有问题的人不会注意到,会很高兴地尝试解码它......:-/

但听起来 c# 实现不喜欢它(这是一种有效的方法),所以如果删除它有帮助,应该这样做。

补充一点:UTF-8 不是必需的,ISO-8859-x aka Latin-x 和 7 位 Ascii 也可以。这是因为 Base64 专门设计为仅使用 7 位子集,它适用于所有 7 位 ascii 兼容编码。

【讨论】:

    【解决方案3】:
    string stringToDecrypt = HttpContext.Current.Request.QueryString.ToString()
    

    //更改为 string stringToDecrypt = HttpUtility.UrlDecode(HttpContext.Current.Request.QueryString.ToString())

    【讨论】:

      【解决方案4】:

      如果无法从字符串末尾删除 \0,您可以为每个编码的字符串添加自己的字符,并在解码时将其删除。

      【讨论】:

        【解决方案5】:

        从字符串转换 Base64 的一个问题是,一些转换函数使用前面的“data:image/jpg;base64”,而另一些只接受实际数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-21
          • 1970-01-01
          • 2013-06-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多