Base64 字符串抛出无效字符错误

发布于 2024-07-15 19:08:44 字数 698 浏览 6 评论 0原文

我不断收到 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”,但我认为甚至没有做任何事情,即使修剪掉它仍然会抛出)。 我什至将整个字符串复制并粘贴到测试方法中,然后对其进行压缩/解压缩。 工作正常。

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

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

I keep getting a Base64 invalid character error even though I shouldn't.

The program takes an XML file and exports it to a document. If the user wants, it will compress the file as well. The compression works fine and returns a Base64 String which is encoded into UTF-8 and written to a file.

When its time to reload the document into the program I have to check whether its compressed or not, the code is simply:

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

It checks the beginning of the string to see if it has GZips code in it.

Now the thing is, all my tests work. I take a string, compress it, decompress it, and compare it to the original. The problem is when I get the string returned from an ADO Recordset. The string is exactly what was written to the file (with the addition of a "\0" at the end, but I don't think that even does anything, even trimmed off it still throws). I even copy and pasted the entire string into a test method and compress/decompress that. Works fine.

The tests will pass but the code will fail using the exact same string? The only difference is instead of just declaring a regular string and passing it in I'm getting one returned from a recordset.

Any ideas on what am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

做个ˇ局外人 2024-07-22 19:08:45
string stringToDecrypt = HttpContext.Current.Request.QueryString.ToString()

//改成
字符串 stringToDecrypt = HttpUtility.UrlDecode(HttpContext.Current.Request.QueryString.ToString())

string stringToDecrypt = HttpContext.Current.Request.QueryString.ToString()

//change to
string stringToDecrypt = HttpUtility.UrlDecode(HttpContext.Current.Request.QueryString.ToString())

最丧也最甜 2024-07-22 19:08:45

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

If removing \0 from the end of string is impossible, you can add your own character for each string you encode, and remove it on decode.

方圜几里 2024-07-22 19:08:45

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

One gotcha to do with converting Base64 from a string is that some conversion functions use the preceding "data:image/jpg;base64," and others only accept the actual data.

情释 2024-07-22 19:08:44

你说

该字符串与所写入的内容完全相同
到文件(添加
末尾有“\0”,但我不认为
甚至可以做任何事情)。

事实上,它确实做了一些事情(它导致您的代码抛出 FormatException:"Base-64 字符串中的无效字符"),因为 Convert.FromBase64String 不认为“\0”是有效的 Base64 字符。

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

解决方案:去掉零终止符。(也许调用.Trim("\0")

注释

Convert.FromBase64String 的 MSDN 文档说它会抛出 FormatException

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

-或-

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

然后

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

You say

The string is exactly what was written
to the file (with the addition of a
"\0" at the end, but I don't think
that even does anything).

In fact, it does do something (it causes your code to throw a FormatException:"Invalid character in a Base-64 string") because the Convert.FromBase64String does not consider "\0" to be a valid Base64 character.

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

Solution: Get rid of the zero termination. (Maybe call .Trim("\0"))

Notes:

The MSDN docs for Convert.FromBase64String say it will throw a FormatException when

The length of s, ignoring white space
characters, is not zero or a multiple
of 4.

-or-

The format of s is invalid. s contains a non-base 64 character, more
than two padding characters, or a
non-white space character among the
padding characters.

and that

The base 64 digits in ascending order
from zero are the uppercase characters
'A' to 'Z', lowercase characters 'a'
to 'z', numerals '0' to '9', and the
symbols '+' and '/'.

梦里泪两行 2024-07-22 19:08:44

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

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

一个小的附加评论:UTF-8 不是必需的,ISO-8859-x 又名 Latin-x,7 位 Ascii 也可以工作。 这是因为 Base64 专门设计为仅使用 7 位子集,该子集适用于所有 7 位 ascii 兼容编码。

Whether null char is allowed or not really depends on base64 codec in question.
Given vagueness of Base64 standard (there is no authoritative exact specification), many implementations would just ignore it as white space. And then others can flag it as a problem. And buggiest ones wouldn't notice and would happily try decoding it... :-/

But it sounds c# implementation does not like it (which is one valid approach) so if removing it helps, that should be done.

One minor additional comment: UTF-8 is not a requirement, ISO-8859-x aka Latin-x, and 7-bit Ascii would work as well. This because Base64 was specifically designed to only use 7-bit subset which works with all 7-bit ascii compatible encodings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文