java - Java 中由 Base64 和 RFC2047 编码的解码字符串(来自标头)
问题描述
我正在开发一个函数来解码在 Java 中以 Base64 和 RFC2047 编码的字符串(来自标头)。
鉴于此标头:
SGVhZGVyOiBoZWFkZXJ2YWx1ZQ0KQmFkOiBOYW1lOiBiYWRuYW1ldmFsdWUNClVuaWNvZGU6ID0/VVRGLTg/Qj81YmV4NXF5eTU2dUw2SUNNNTZ1TDVMcTY3N3lNNWJleDVxeXk2WUdVNklDTTZZR1U/PSA9P1VURi04P0I/NUxxNjc3eU01YmV4NW9tQTVMaU41cXl5Nzd5TTVZdS81cGE5NXBhODVMcTY0NENDPz0NCg0K
我的预期输出是:
Header: headervalue Bad: Name: badnamevalue Unicode: 己欲立而立人,己欲达而达人,己所不欲,勿施于人。</p>
我找到并尝试过的唯一相关功能是Base64.decodeBase64(headers)
,它在打印出来时会产生这个:
标头:headervalue 错误:名称:badnamevalue Unicode:=?UTF-8?B?5bex5qyy56uL6ICM56uL5Lq677yM5bex5qyy6YGU6ICM6YGU?= =?UTF-8?B?5Lq677yM5bex5omA5LiN5qyy77yM5Yu/5pa95pa85Lq644CC?=
为了解决这个问题,我一直在尝试通过将返回的字节数组转换Base64.decodeBase64(headers)
为 InputStream 来尝试 MimeUtility.decode(),但结果与上面相同。
InputStream headerStream = new ByteArrayInputStream(Base64.decodeBase64(headers));
InputStream result = MimeUtility.decode(headerStream, "quoted-printable");
一直在互联网上搜索,但尚未找到解决方案,想知道是否有人知道从结果字节数组中解码 MIME 标头的方法?
任何帮助表示赞赏!这也是我的第一个堆栈溢出帖子,如果我遗漏了什么,请道歉,但如果我可以提供更多信息,请告诉我!
解决方案
你在那里的base64实际上就是你粘贴的。包括奇怪的 =?UTF-8?B? 怪异。
接下来的东西又是base64。
您的 base-64 编码数据中有 base64 编码数据。正如 Xzibit 所说:我在你的 base64 中加入了一些 Base64,这样你就可以在使用 base64 的同时使用 base64。为什么我突然觉得老了?
换句话说,你得到的base64输入是一个疯狂的人发明的一种疯狂的、效率极低的格式。
我的建议是你告诉他们想出一些不那么疯狂的东西。
做不到这一点:
在结果字符串中搜索正则表达式模式,然后再次将 base64 解码应用于中间的内容。
此外,您正在使用一些第三方 base64 解码器,可能是 apache。Apache 库往往很糟糕。Base64 被嵌入到 java 中,这里没有理由使用更差的库。我已经解决了;此代码段中的 Base64 是java.util.Base64
. 它的 API 略有不同。
String sourceB64 = "SGV..."; // that input base64 you have.
byte[] sourceBytes = Base64.decodeBase64(sourceB64);
String source = new String(sourceBytes, StandardCharsets.UTF_8);
Pattern p = Pattern.compile("=\\?UTF-8\\?B\\?(.*?)\\?=");
Matcher m = p.matcher(source);
StringBuilder out = new StringBuilder();
int curPos = 0;
while (m.find()) {
out.append(source.substring(curPos, m.start()));
curPos = m.end();
String content = new String(Base64.getDecoder().decode(m.group(1)), StandardCharsets.UTF_8);
out.append(content);
}
out.append(source.substring(curPos));
System.out.println(out.toString());
如果我运行它,我会得到:
Header: headervalue
Bad: Name: badnamevalue
Unicode: 己欲立而立人,己欲達而達 人,己所不欲,勿施於人。
这看起来完全像你想要的。
该代码的解释:
- 它首先对输入进行 base64 解码,然后将其转换为字符串。(您使用 InputStream 的想法是一个红鲱鱼。这在这里根本没有帮助。您只想将字节转换为字符串,您按照该片段的第 3 行进行操作。传递字节数组和编码这些字节在,这就是你需要做的)。
=?UTF-8?B?--base64here--?=
然后它继续在你的 base64 内部寻找。base64-in-the-base64。- 然后它解码那个base64,以同样的方式把它变成一个字符串,然后替换它。
- 它只是
=?UTF-8?B?...?=
逐字添加这些片段之外的所有内容。
推荐阅读
- typescript - 如何将任何字符串选项添加到打字稿文字字符串枚举?
- python - 根据 Pandas 中的 3 个常见列值连接 3 个单独的 DataFrame
- javascript - 没有导出成员 OpaqueToken
- c# - 反序列化同一字段的字符串和字符串数组
- javascript - Node.js、POST 和 DELETE 请求
- python-3.x - 调用 CF API 登录一次性密码时出错
- stripe-payments - 这是接受一次性付款的可接受方式吗?
- paraview - Paraview:将轴添加到与方向轴不对齐的平面
- python - Django - 如何将自定义对象分配为模型属性并在该对象中获取该模型实例?
- php - 将 TIMESTAMPDIFF() 插入到同一数据库表中的现有列中