非法参数异常的解决方案:Last encoded character is a valid base 64 alphabet but not a possible value

导读:本篇文章讲解 非法参数异常的解决方案:Last encoded character is a valid base 64 alphabet but not a possible value,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

问题

今天在开发的过程中,前端传过来的是base64的图片地址,如下所示:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gNzUK/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgBkAGQAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZ…1OSXJf3djzM2Nx/dekNpcD+Fvyr07+wrXPVqcPD9oepaqIaR5d9luP7jflThb3A6qw/CvUh4csz3al/wCEbtezNTsToeXrHN7/AJVZiEi4JB/KvSR4ZtT0dh+FSL4XtT/GfyppMTlFH//Z

因为图片地址过长,只展示部分图片地址。

后端接到base64的图片地址后,需要解析出改地址信息,当时考虑到使用的是commonsc-codec进行解密,但报出来如下的错误:

Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible value. Expected the discarded bits to be zero.

在这里插入图片描述
通过断点的方式,查询出报错信息的位置,如下所示。

分析问题

于是,到源码里面看报错信息的出处,原来问题出现在这里,commonsc-codec在升级之后,其内部做了一个validateCharacter校验,报出这样的错误。


/**
     * Validates whether decoding the final trailing character is possible in the context
     * of the set of possible base 64 values.
     *
     * <p>The character is valid if the lower bits within the provided mask are zero. This
     * is used to test the final trailing base-64 digit is zero in the bits that will be discarded.
     *
     * @param emptyBitsMask The mask of the lower bits that should be empty
     * @param context the context to be used
     *
     * @throws IllegalArgumentException if the bits being checked contain any non-zero value
     */
    private static void validateCharacter(final int emptyBitsMask, final Context context) {
        if ((context.ibitWorkArea & emptyBitsMask) != 0) {
            throw new IllegalArgumentException(
                "Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible value. " +
                "Expected the discarded bits to be zero.");
        }
    }

这段代码是什么意思呢?翻译成中文:

验证在一组可能的 base 64 值的上下文中是否可以解码最后一个尾随字符。如果提供的掩码中的较低位为零,则该字符有效。这用于测试最终的尾随 base-64 数字在将被丢弃的位中是否为零。

通过翻译可以了解到该方法的作用,然后再分析这两个参数:

  • ibitWorkArea: 位处理的基本位数

  • numBitsToDrop: 应该为空的低位数目

可以看出当 context.ibitWorkArea & numBitsToDrop不为0时就会抛出异常,实际上只有base64严格模式编码下,才可能会为0,松散模式不会为0

解决问题

方式一

commons-codec版本更新到1.15,最新的源码已经处理了该问题。

引入jar包

 <dependency>
    <groupId>commons-codec</groupId>
     <artifactId>commons-codec</artifactId>
     <version>1.15</version>
 </dependency>

查看源码:

private void validateCharacter(final int emptyBitsMask, final Context context) {
        if (isStrictDecoding() && (context.ibitWorkArea & emptyBitsMask) != 0) {
            throw new IllegalArgumentException(
                "Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. " +
                "Expected the discarded bits from the character to be zero.");
        }
    }

方式二

可以使用谷歌的guava来替换common-codec来解密base64格式的文件

 <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
 <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>30.1.1-jre</version>
 </dependency>

如下代码解析代码:

 byte[] imageByte = BaseEncoding.base64().decode(imageString);

结果能正常解析。

扩展备注

base64的严格模式和松散模式定义,直接引用源码了

松散模式

任何尾随位都尽可能组合成 8 位字节。其余的被丢弃。

严格模式

严格模式: 如果尾随位,解码将引发 {@link IllegalArgumentException}不是有效编码的一部分。 最后一个字符中的任何未使用的位必须为零。 不允许对整个最终字符进行不可能计数。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99219.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!