为了账号安全,请及时绑定邮箱和手机立即绑定

将字节数组解码为包含“-”和“_”等字符的 base64 时出错

将字节数组解码为包含“-”和“_”等字符的 base64 时出错

明月笑刀无情 2021-10-27 09:44:52
我正在尝试对字节数组进行 base64 解码,只要我的字节数组不包含任何像“-”或“_”这样的字符,一切都运行良好。但是每当字节数组包含“-”时,我都会收到一个异常java.lang.IllegalArgumentException: Illegal base64 character 2d    at java.util.Base64$Decoder.decode0(Base64.java:714)    at java.util.Base64$Decoder.decode(Base64.java:526)当字节数组包含'_'时,异常是java.lang.IllegalArgumentException: Illegal base64 character 5f    at java.util.Base64$Decoder.decode0(Base64.java:714)    at java.util.Base64$Decoder.decode(Base64.java:526)即字符 2d 到 5f 之后的代码差异。这些代码是什么。无论代码中的这些字符如何,我如何解码任何值?这是我的代码片段:import java.util.Properties;import java.util.Base64;import java.io.*;...public class BasicSample {    public static void main(String[] args) {      byte[] encoded = res.getBytes("s_id");      System.out.printf("\nInside Byte %s\n",new String(encoded) );      try {        byte[] decoded = Base64.getDecoder().decode(encoded);        System.out.printf("\nDecoded Byte %s\n",new String(decoded, "UTF-8") );      } catch(Exception e) {        e.printStackTrace();      }   }}
查看完整描述

2 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

解决方案

更换'-'用'+'和'_'用'/'如下行


byte[] decoded = Base64.getDecoder().decode(encoded.replace('-', '+').replace('_', '/'));

基本原理

有Base64编码和Base64url编码。除了上面指出的两个字符替换之外,它们完全相同。


查看RFC 4648中的表 1 和表 2 :


                Table 1: The Base 64 Alphabet


 Value Encoding  Value Encoding  Value Encoding  Value Encoding

     0 A            17 R            34 i            51 z

     1 B            18 S            35 j            52 0

     2 C            19 T            36 k            53 1

     3 D            20 U            37 l            54 2

     4 E            21 V            38 m            55 3

     5 F            22 W            39 n            56 4

     6 G            23 X            40 o            57 5

     7 H            24 Y            41 p            58 6

     8 I            25 Z            42 q            59 7

     9 J            26 a            43 r            60 8

    10 K            27 b            44 s            61 9

    11 L            28 c            45 t            62 +

    12 M            29 d            46 u            63 /

    13 N            30 e            47 v

    14 O            31 f            48 w         (pad) =

    15 P            32 g            49 x

    16 Q            33 h            50 y


[...]


                Table 2: The "URL and Filename safe" Base 64 Alphabet


 Value Encoding  Value Encoding  Value Encoding  Value Encoding

     0 A            17 R            34 i            51 z

     1 B            18 S            35 j            52 0

     2 C            19 T            36 k            53 1

     3 D            20 U            37 l            54 2

     4 E            21 V            38 m            55 3

     5 F            22 W            39 n            56 4

     6 G            23 X            40 o            57 5

     7 H            24 Y            41 p            58 6

     8 I            25 Z            42 q            59 7

     9 J            26 a            43 r            60 8

    10 K            27 b            44 s            61 9

    11 L            28 c            45 t            62 - (minus)

    12 M            29 d            46 u            63 _

    13 N            30 e            47 v           (underline)

    14 O            31 f            48 w

    15 P            32 g            49 x

    16 Q            33 h            50 y         (pad) =

这是RFC的另一个引用:


这种编码可以称为“base64url”。这种编码不应被视为与“base64”编码相同,不应仅称为“base64”。除非另有说明,“base64”指的是上一节中的 base64。这种编码在技术上与前一种编码相同,除了 62:nd 和 63:rd 字母字符,如表 2 所示。


查看完整回答
反对 回复 2021-10-27
?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

根据RFC 2045,表 1:Base64 字母既不是字母表的一部分,-也不_是字母表的一部分。Base64解码器只使用字母表中存在的字符,您不能只解码任意字符。


                Table 1: The Base64 Alphabet


 Value Encoding  Value Encoding  Value Encoding  Value Encoding

     0 A            17 R            34 i            51 z

     1 B            18 S            35 j            52 0

     2 C            19 T            36 k            53 1

     3 D            20 U            37 l            54 2

     4 E            21 V            38 m            55 3

     5 F            22 W            39 n            56 4

     6 G            23 X            40 o            57 5

     7 H            24 Y            41 p            58 6

     8 I            25 Z            42 q            59 7

     9 J            26 a            43 r            60 8

    10 K            27 b            44 s            61 9

    11 L            28 c            45 t            62 +

    12 M            29 d            46 u            63 /

    13 N            30 e            47 v

    14 O            31 f            48 w         (pad) =

    15 P            32 g            49 x

    16 Q            33 h            50 y

正如 Roland Illig 指出的那样,您可能正在处理 URL 友好的 Base 64 变体,其中_replaces+和-replaces /。在这种情况下,在解码之前恢复更改可能就足够了:


String raw = new String(res.getBytes("s_id"));

String encoded = raw.replace("_", "+").replace("-", "/");

String decoded = Base64.getDecoder().decode(encoded);

然而,如果没有看到服务器端编码代码,就无法知道数据实际上是如何编码的。


查看完整回答
反对 回复 2021-10-27
  • 2 回答
  • 0 关注
  • 134 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信