Zzzz二哥
2021-07-22 09:38
采纳率: 100%
浏览 221

同一个base64字符串PHP和JAVA decode结果不一样 求对应的PHP代码

$str = "+Rc63TwpY3vrNrF8Rk5Y+Q==";
php base64_decode 结果是 string(16) "�:�<)c{�6�|FNX�"
JAVA Base64.getDecoder().decode()后是 [B@6d21714c

JAVA代码


```java
public static class Decoder {
        private final boolean isURL;
        private final boolean isMIME;
        private static final int[] fromBase64 = new int[256];
        private static final int[] fromBase64URL;
        static final Base64.Decoder RFC4648;
        static final Base64.Decoder RFC4648_URLSAFE;
        static final Base64.Decoder RFC2045;

        private Decoder(boolean isURL, boolean isMIME) {
            this.isURL = isURL;
            this.isMIME = isMIME;
        }
        //代码定位的是这个方法
        public byte[] decode(byte[] src) {
            byte[] dst = new byte[this.outLength(src, 0, src.length)];
            int ret = this.decode0(src, 0, src.length, dst);
            if (ret != dst.length) {
                dst = Arrays.copyOf(dst, ret);
            }

            return dst;
        }

        public byte[] decode(String src) {
            return this.decode(src.getBytes(StandardCharsets.ISO_8859_1));
        }

        public int decode(byte[] src, byte[] dst) {
            int len = this.outLength(src, 0, src.length);
            if (dst.length < len) {
                throw new IllegalArgumentException("Output byte array is too small for decoding all input bytes");
            } else {
                return this.decode0(src, 0, src.length, dst);
            }
        }

        public ByteBuffer decode(ByteBuffer buffer) {
            int pos0 = buffer.position();

            try {
                byte[] src;
                int sp;
                int sl;
                if (buffer.hasArray()) {
                    src = buffer.array();
                    sp = buffer.arrayOffset() + buffer.position();
                    sl = buffer.arrayOffset() + buffer.limit();
                    buffer.position(buffer.limit());
                } else {
                    src = new byte[buffer.remaining()];
                    buffer.get(src);
                    sp = 0;
                    sl = src.length;
                }

                byte[] dst = new byte[this.outLength(src, sp, sl)];
                return ByteBuffer.wrap(dst, 0, this.decode0(src, sp, sl, dst));
            } catch (IllegalArgumentException var7) {
                buffer.position(pos0);
                throw var7;
            }
        }

        public InputStream wrap(InputStream is) {
            Objects.requireNonNull(is);
            return new Base64.DecInputStream(is, this.isURL ? fromBase64URL : fromBase64, this.isMIME);
        }

        private int outLength(byte[] src, int sp, int sl) {
            int[] base64 = this.isURL ? fromBase64URL : fromBase64;
            int paddings = 0;
            int len = sl - sp;
            if (len == 0) {
                return 0;
            } else if (len < 2) {
                if (this.isMIME && base64[0] == -1) {
                    return 0;
                } else {
                    throw new IllegalArgumentException("Input byte[] should at least have 2 bytes for base64 bytes");
                }
            } else {
                if (this.isMIME) {
                    int n = 0;

                    while(sp < sl) {
                        int b = src[sp++] & 255;
                        if (b == 61) {
                            len -= sl - sp + 1;
                            break;
                        }

                        if (base64[b] == -1) {
                            ++n;
                        }
                    }

                    len -= n;
                } else if (src[sl - 1] == 61) {
                    ++paddings;
                    if (src[sl - 2] == 61) {
                        ++paddings;
                    }
                }

                if (paddings == 0 && (len & 3) != 0) {
                    paddings = 4 - (len & 3);
                }

                return 3 * ((len + 3) / 4) - paddings;
            }
        }

        private int decode0(byte[] src, int sp, int sl, byte[] dst) {
            int[] base64 = this.isURL ? fromBase64URL : fromBase64;
            int dp = 0;
            int bits = 0;
            int shiftto = 18;

            while(sp < sl) {
                int b = src[sp++] & 255;
                if ((b = base64[b]) < 0) {
                    if (b == -2) {
                        if ((shiftto != 6 || sp != sl && src[sp++] == 61) && shiftto != 18) {
                            break;
                        }

                        throw new IllegalArgumentException("Input byte array has wrong 4-byte ending unit");
                    }

                    if (!this.isMIME) {
                        throw new IllegalArgumentException("Illegal base64 character " + Integer.toString(src[sp - 1], 16));
                    }
                } else {
                    bits |= b << shiftto;
                    shiftto -= 6;
                    if (shiftto < 0) {
                        dst[dp++] = (byte)(bits >> 16);
                        dst[dp++] = (byte)(bits >> 8);
                        dst[dp++] = (byte)bits;
                        shiftto = 18;
                        bits = 0;
                    }
                }
            }

            if (shiftto == 6) {
                dst[dp++] = (byte)(bits >> 16);
            } else if (shiftto == 0) {
                dst[dp++] = (byte)(bits >> 16);
                dst[dp++] = (byte)(bits >> 8);
            } else if (shiftto == 12) {
                throw new IllegalArgumentException("Last unit does not have enough valid bits");
            }

            do {
                if (sp >= sl) {
                    return dp;
                }
            } while(this.isMIME && base64[src[sp++]] < 0);

            throw new IllegalArgumentException("Input byte array has incorrect ending byte at " + sp);
        }

        static {
            Arrays.fill(fromBase64, -1);

            int i;
            for(i = 0; i < Base64.Encoder.toBase64.length; fromBase64[Base64.Encoder.toBase64[i]] = i++) {
            }

            fromBase64[61] = -2;
            fromBase64URL = new int[256];
            Arrays.fill(fromBase64URL, -1);

            for(i = 0; i < Base64.Encoder.toBase64URL.length; fromBase64URL[Base64.Encoder.toBase64URL[i]] = i++) {
            }

            fromBase64URL[61] = -2;
            RFC4648 = new Base64.Decoder(false, false);
            RFC4648_URLSAFE = new Base64.Decoder(true, false);
            RFC2045 = new Base64.Decoder(false, true);
        }
    }

```

3条回答 默认 最新

相关推荐 更多相似问题