返回顶部
首页 > 资讯 > 精选 >安卓base64与其他语言base64算法还原出来差异问题???
  • 468
分享到

安卓base64与其他语言base64算法还原出来差异问题???

android算法 2023-08-16 14:08:34 468人浏览 安东尼
摘要

今天逆向某app时,发现了最后一步base64编码后后几位不一致。 之前有遇到空格及换行等问题,eg : 在在线工具生成对比后,确实后几位有出入。 回看了代码base64就是调用的标准算法,且也没更换码表。 # hyqBFS+m9jNbm

今天逆向某app时,发现了最后一步base64编码后后几位不一致。

之前有遇到空格及换行等问题,eg :
在这里插入图片描述

在在线工具生成对比后,确实后几位有出入。
回看了代码base64就是调用的标准算法,且也没更换码表。

# hyqBFS+m9jNbmIrG0x0dAYJzG5jiqgwFr+SxV0hRMwGDFcDI+5oJxwtU1mcglidAqD7xOELt1bcUpO1vacWssh487vfpQ98NntxvTIUcVrnHUKNDvwOVKCwp++nRePzSfW3y6f3F/4P0fZrdMLy8S5G9A95UHF2ZC3aZoSOw89+92auduE8fx8CLSEcyqHMNYglPCspJ7U5D6MgHgi9DNG+7e962E/xDDuO2RCjCmL8lznpb/7nHv9gDbg7WfBmAFAEZlwya74RkARDQ+2y6i/no60H1W33ocZb3R96ejQ0kPrzuqWB/hOnoavR7TPyhpEcdFb/1MgyRAatn3p14Lpp8AzT50CXmW5MIfKdUOTggAHm51fRfBL/kfwzmeC2KVCCyYsmj/A8vx9WzL5YwQtGIe2/JCbKgR4h8SW/x8V5RyMJX1OOj0B82TljOarPAxAGUyfKWqWlAWcJuW2maeR78AzL6Q9aW9tiQfho3loewpVfjXW0DQjCF1hpoaHrumId6gxsWet48O+7dTKrkbR+dSQz1a+h4C1BEypYLy+Sy7mYVG6uGjsYqc+HeT2qocf/+FQVqrmYGSEua1Xg5IpJKHz5uV5+6dn4bceDZ3AjWUuB2Rac25h7SHeNDJobYsdxFuwYiG9+AcncZv+1nrSA0aqhqn1oYsl4wkRIsV0UYHA4N9yTuio730mZQy2NR7jQyeMQUZa8MIVf1MacX8kqrtoQjEfApNUEOblCqPFxp1wWzpAB9YZ0mpwFjqzXLTd4vDhH93LzV0+OL51PamGH0uy63mvK+GrmDjybkVXV2Qc/mp/DeGTFFf0Cz10ul0Be63zR8haMMwD/nRnLgy/JXTfKaAc/LNpkryKtfaiMQ574rCaXKq3+izLPStMl4b3eVnBxzRwru+V1Tkjp229t46fh29ZvfnhH9nZGkWbvoq4bjk49qDJMC264aqkkrVTsxFLf1RWAPtoMdaywUZQ==# hyqBFS+m9jNbmIrG0x0dAYJzG5jiqgwFr+SxV0hRMwGDFcDI+5oJxwtU1mcglidAqD7xOELt1bcUpO1vacWssh487vfpQ98NntxvTIUcVrnHUKNDvwOVKCwp++nRePzSfW3y6f3F/4P0fZrdMLy8S5G9A95UHF2ZC3aZoSOw89+92auduE8fx8CLSEcyqHMNYglPCspJ7U5D6MgHgi9DNG+7e962E/xDDuO2RCjCmL8lznpb/7nHv9gDbg7WfBmAFAEZlwya74RkARDQ+2y6i/no60H1W33ocZb3R96ejQ0kPrzuqWB/hOnoavR7TPyhpEcdFb/1MgyRAatn3p14Lpp8AzT50CXmW5MIfKdUOTggAHm51fRfBL/kfwzmeC2KVCCyYsmj/A8vx9WzL5YwQtGIe2/JCbKgR4h8SW/x8V5RyMJX1OOj0B82TljOarPAxAGUyfKWqWlAWcJuW2maeR78AzL6Q9aW9tiQfho3loewpVfjXW0DQjCF1hpoaHrumId6gxsWet48O+7dTKrkbR+dSQz1a+h4C1BEypYLy+Sy7mYVG6uGJSYqc+HeT2qocf/+FQVqrmYGSEua1Xg5IpJKHz5uV5+6dn4bceDZ3AjWUuB2Rac25h7SHeNDJobYsdxFuwYiG9+AcncZv+1nrSA0aqhqn1oYsl4wkRIsV0UYHA4N9yTuIO730mZQy2NR7jQyemQUZa8MIVf1mAcX8kqrtoQjEfApNUEOblCqPFxp1wWzpAB9YZ0mpwFjqzXLTd4vDhH93LzV0+OL51PamGH0uy63mvK+GrmDjybkVXV2Qc/mp/DeGTFFf0Cz10ul0Be63zR8haMMwD/nRnLgy/JXTfKaAc/LNpkryKtfAiMQ574rCaXKq3+izLPStMl4b3eVnBxzRwru+V1Tkjp229t46fh29ZvfnhH9nZGkWbvoq4bjk49qDJMC264aqkkrpALg44xLbw3UBRPkLDltKQ==

众所周知,base64是以6位进行便宜,而正常是8个bit位,这样就会缺两位进行==补位。

祥细解说及码表更换base64:https://codeooo.blog.csdn.net/article/details/119810268

在这里插入图片描述
经过分析代码:
在这里插入图片描述
而我们常规的:

    public static final String m54667a(String str, String str2) {        String str3 = "(this as java.lang.String).getBytes(charset)";        m73751b(str, "content");        m73751b(str2, "passWord");        byte[] bArr = null;        try {            byte[] bytes = str2.getBytes(StandardCharsets.UTF_8);            m73745a((Object) bytes, str3);            SecreTKEySpec secretKeySpec = new SecretKeySpec(bytes, "AES");            Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");            Charset forName = StandardCharsets.UTF_8;            m73745a((Object) forName, "Charset.forName(charsetName)");            byte[] bytes2 = str.getBytes(forName);            m73745a((Object) bytes2, str3);            byte[] bytes3 = str2.getBytes(StandardCharsets.UTF_8);            m73745a((Object) bytes3, str3);            instance.init(1, secretKeySpec, new IvParameterSpec(bytes3));            String encodeToString = Base64.getEncoder().encodeToString(instance.doFinal(bytes2));            m73745a((Object) encodeToString, "Base64.encodeToString(en…ptResult, Base64.NO_WRAP)");            return encodeToString;        } catch (Exception e) {            e.printStackTrace();            return "";        }    }

在这里插入图片描述

故而我们可以使用:

引入一个三方jar包:
com.akdeniz.Googleplaycrawler.misc.Base64

import com.akdeniz.googleplaycrawler.misc.Base64; //导入依赖的package包/类public class encryptString {        public static String main(String str2Encrypt) throws Exception {        byte[] keyByteArray = Base64.decode(GOOGLE_PUBLIC_KEY, Base64.DEFAULT);        byte[] header = new byte[5];        byte[] digest = MessageDigest.getInstance("SHA-1").digest(keyByteArray);        header[0] = 0;        System.arraycopy(digest, 0, header, 1, 4);        PublicKey publicKey = createKey(keyByteArray);        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING");        byte[] bytes2Encrypt = str2Encrypt.getBytes("UTF-8");        int len = ((bytes2Encrypt.length - 1) / 86) + 1;        byte[] cryptedBytes = new byte[len * 133];        for (int j = 0; j < len; j++) {            cipher.init(1, publicKey);            byte[] arrayOfByte4 = cipher.doFinal(bytes2Encrypt, j * 86, (bytes2Encrypt.length - j * 86));            System.arraycopy(header, 0, cryptedBytes, j * 133, header.length);            System.arraycopy(arrayOfByte4, 0, cryptedBytes, j * 133 + header.length, arrayOfByte4.length);        }        return Base64.encodeToString(cryptedBytes, 10);    }}

另一种解决方案:

直接将安卓的base64代码copy进来,就一个文件

在这里插入图片描述

package Android.util;import java.io.UnsupportedEncodingException;public class Base64 {        public static final int DEFAULT = 0;        public static final int NO_PADDING = 1;        public static final int NO_WRAP = 2;        public static final int CRLF = 4;        public static final int URL_SAFE = 8;        public static final int NO_CLOSE = 16;    //  --------------------------------------------------------    //  shared code    //  --------------------------------------------------------     static abstract class Coder {        public byte[] output;        public int op;                public abstract boolean process(byte[] input, int offset, int len, boolean finish);                public abstract int maxOutputSize(int len);    }    //  --------------------------------------------------------    //  decoding    //  --------------------------------------------------------        public static byte[] decode(String str, int flags) {        return decode(str.getBytes(), flags);    }        public static byte[] decode(byte[] input, int flags) {        return decode(input, 0, input.length, flags);    }        public static byte[] decode(byte[] input, int offset, int len, int flags) {        // Allocate space for the most data the input could represent.        // (It could contain less if it contains whitespace, etc.)        Decoder decoder = new Decoder(flags, new byte[len*3/4]);        if (!decoder.process(input, offset, len, true)) {            throw new IllegalArgumentException("bad base-64");        }        // Maybe we got lucky and allocated exactly enough output space.        if (decoder.op == decoder.output.length) {            return decoder.output;        }        // Need to shorten the array, so allocate a new one of the        // right size and copy.        byte[] temp = new byte[decoder.op];        System.arraycopy(decoder.output, 0, temp, 0, decoder.op);        return temp;    }     static class Decoder extends Coder {                private static final int DECODE[] = {            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,            -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,        };                private static final int DECODE_WEBSAFE[] = {            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,            -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,        };                private static final int SKIP = -1;        private static final int EQUALS = -2;                private int state;   // state number (0 to 6)        private int value;        final private int[] alphabet;        public Decoder(int flags, byte[] output) {            this.output = output;            alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;            state = 0;            value = 0;        }                public int maxOutputSize(int len) {            return len * 3/4 + 10;        }                public boolean process(byte[] input, int offset, int len, boolean finish) {            if (this.state == 6) return false;            int p = offset;            len += offset;            // Using local variables makes the decoder about 12%            // faster than if we manipulate the member variables in            // the loop.  (Even alphabet makes a measurable            // difference, which is somewhat surprising to me since            // the member variable is final.)            int state = this.state;            int value = this.value;            int op = 0;            final byte[] output = this.output;            final int[] alphabet = this.alphabet;            while (p < len) {                // Try the fast path:  we're starting a new tuple and the                // next four bytes of the input stream are all data                // bytes.  This corresponds to going through states                // 0-1-2-3-0.  We expect to use this method for most of                // the data.                //                // If any of the next four bytes of input are non-data                // (whitespace, etc.), value will end up negative.  (All                // the non-data values in decode are small negative                // numbers, so shifting any of them up and or'ing them                // together will result in a value with its top bit set.)                //                // You can remove this whole block and the output should                // be the same, just slower.                if (state == 0) {                    while (p+4 <= len &&                           (value = ((alphabet[input[p] & 0xff] << 18) |         (alphabet[input[p+1] & 0xff] << 12) |         (alphabet[input[p+2] & 0xff] << 6) |         (alphabet[input[p+3] & 0xff]))) >= 0) {                        output[op+2] = (byte) value;                        output[op+1] = (byte) (value >> 8);                        output[op] = (byte) (value >> 16);                        op += 3;                        p += 4;                    }                    if (p >= len) break;                }                // The fast path isn't available -- either we've read a                // partial tuple, or the next four input bytes aren't all                // data, or whatever.  Fall back to the slower state                // machine implementation.                int d = alphabet[input[p++] & 0xff];                switch (state) {                case 0:                    if (d >= 0) {                        value = d;                        ++state;                    } else if (d != SKIP) {                        this.state = 6;                        return false;                    }                    break;                case 1:                    if (d >= 0) {                        value = (value << 6) | d;                        ++state;                    } else if (d != SKIP) {                        this.state = 6;                        return false;                    }                    break;                case 2:                    if (d >= 0) {                        value = (value << 6) | d;                        ++state;                    } else if (d == EQUALS) {                        // Emit the last (partial) output tuple;                        // expect exactly one more padding character.                        output[op++] = (byte) (value >> 4);                        state = 4;                    } else if (d != SKIP) {                        this.state = 6;                        return false;                    }                    break;                case 3:                    if (d >= 0) {                        // Emit the output triple and return to state 0.                        value = (value << 6) | d;                        output[op+2] = (byte) value;                        output[op+1] = (byte) (value >> 8);                        output[op] = (byte) (value >> 16);                        op += 3;                        state = 0;                    } else if (d == EQUALS) {                        // Emit the last (partial) output tuple;                        // expect no further data or padding characters.                        output[op+1] = (byte) (value >> 2);                        output[op] = (byte) (value >> 10);                        op += 2;                        state = 5;                    } else if (d != SKIP) {                        this.state = 6;                        return false;                    }                    break;                case 4:                    if (d == EQUALS) {                        ++state;                    } else if (d != SKIP) {                        this.state = 6;                        return false;                    }                    break;                case 5:                    if (d != SKIP) {                        this.state = 6;                        return false;                    }                    break;                }            }            if (!finish) {                // We're out of input, but a future call could provide                // more.                this.state = state;                this.value = value;                this.op = op;                return true;            }            // Done reading input.  Now figure out where we are left in            // the state machine and finish up.            switch (state) {            case 0:                // Output length is a multiple of three.  Fine.                break;            case 1:                // Read one extra input byte, which isn't enough to                // make another output byte.  Illegal.                this.state = 6;                return false;            case 2:                // Read two extra input bytes, enough to emit 1 more                // output byte.  Fine.                output[op++] = (byte) (value >> 4);                break;            case 3:                // Read three extra input bytes, enough to emit 2 more                // output bytes.  Fine.                output[op++] = (byte) (value >> 10);                output[op++] = (byte) (value >> 2);                break;            case 4:                // Read one padding '=' when we expected 2.  Illegal.                this.state = 6;                return false;            case 5:                // Read all the padding '='s we expected and no more.                // Fine.                break;            }            this.state = state;            this.op = op;            return true;        }    }    //  --------------------------------------------------------    //  encoding    //  --------------------------------------------------------        public static String encodeToString(byte[] input, int flags) {        try {            return new String(encode(input, flags), "US-ASCII");        } catch (UnsupportedEncodingException e) {            // US-ASCII is guaranteed to be available.            throw new AssertionError(e);        }    }        public static String encodeToString(byte[] input, int offset, int len, int flags) {        try {            return new String(encode(input, offset, len, flags), "US-ASCII");        } catch (UnsupportedEncodingException e) {            // US-ASCII is guaranteed to be available.            throw new AssertionError(e);        }    }        public static byte[] encode(byte[] input, int flags) {        return encode(input, 0, input.length, flags);    }        public static byte[] encode(byte[] input, int offset, int len, int flags) {        Encoder encoder = new Encoder(flags, null);        // Compute the exact length of the array we will produce.        int output_len = len / 3 * 4;        // Account for the tail of the data and the padding bytes, if any.        if (encoder.do_padding) {            if (len % 3 > 0) {                output_len += 4;            }        } else {            switch (len % 3) {                case 0: break;                case 1: output_len += 2; break;                case 2: output_len += 3; break;            }        }        // Account for the newlines, if any.        if (encoder.do_newline && len > 0) {            output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *                (encoder.do_cr ? 2 : 1);        }        encoder.output = new byte[output_len];        encoder.process(input, offset, len, true);        assert encoder.op == output_len;        return encoder.output;    }     static class Encoder extends Coder {                public static final int LINE_GROUPS = 19;                private static final byte ENCODE[] = {            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',        };                private static final byte ENCODE_WEBSAFE[] = {            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',        };        final private byte[] tail;         int tailLen;        private int count;        final public boolean do_padding;        final public boolean do_newline;        final public boolean do_cr;        final private byte[] alphabet;        public Encoder(int flags, byte[] output) {            this.output = output;            do_padding = (flags & NO_PADDING) == 0;            do_newline = (flags & NO_WRAP) == 0;            do_cr = (flags & CRLF) != 0;            alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;            tail = new byte[2];            tailLen = 0;            count = do_newline ? LINE_GROUPS : -1;        }                public int maxOutputSize(int len) {            return len * 8/5 + 10;        }        public boolean process(byte[] input, int offset, int len, boolean finish) {            // Using local variables makes the encoder about 9% faster.            final byte[] alphabet = this.alphabet;            final byte[] output = this.output;            int op = 0;            int count = this.count;            int p = offset;            len += offset;            int v = -1;            // First we need to concatenate the tail of the previous call            // with any input bytes available now and see if we can empty            // the tail.            switch (tailLen) {                case 0:                    // There was no tail.                    break;                case 1:                    if (p+2 <= len) {                        // A 1-byte tail with at least 2 bytes of                        // input available now.                        v = ((tail[0] & 0xff) << 16) |((input[p++] & 0xff) << 8) |(input[p++] & 0xff);                        tailLen = 0;                    };                    break;                case 2:                    if (p+1 <= len) {                        // A 2-byte tail with at least 1 byte of input.                        v = ((tail[0] & 0xff) << 16) |((tail[1] & 0xff) << 8) |(input[p++] & 0xff);                        tailLen = 0;                    }                    break;            }            if (v != -1) {                output[op++] = alphabet[(v >> 18) & 0x3f];                output[op++] = alphabet[(v >> 12) & 0x3f];                output[op++] = alphabet[(v >> 6) & 0x3f];                output[op++] = alphabet[v & 0x3f];                if (--count == 0) {                    if (do_cr) output[op++] = '\r';                    output[op++] = '\n';                    count = LINE_GROUPS;                }            }            // At this point either there is no tail, or there are fewer            // than 3 bytes of input available.            // The main loop, turning 3 input bytes into 4 output bytes on            // each iteration.            while (p+3 <= len) {                v = ((input[p] & 0xff) << 16) |                    ((input[p+1] & 0xff) << 8) |                    (input[p+2] & 0xff);                output[op] = alphabet[(v >> 18) & 0x3f];                output[op+1] = alphabet[(v >> 12) & 0x3f];                output[op+2] = alphabet[(v >> 6) & 0x3f];                output[op+3] = alphabet[v & 0x3f];                p += 3;                op += 4;                if (--count == 0) {                    if (do_cr) output[op++] = '\r';                    output[op++] = '\n';                    count = LINE_GROUPS;                }            }            if (finish) {                // Finish up the tail of the input.  Note that we need to                // consume any bytes in tail before any bytes                // remaining in input; there should be at most two bytes                // total.                if (p-tailLen == len-1) {                    int t = 0;                    v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;                    tailLen -= t;                    output[op++] = alphabet[(v >> 6) & 0x3f];                    output[op++] = alphabet[v & 0x3f];                    if (do_padding) {                        output[op++] = '=';                        output[op++] = '=';                    }                    if (do_newline) {                        if (do_cr) output[op++] = '\r';                        output[op++] = '\n';                    }                } else if (p-tailLen == len-2) {                    int t = 0;                    v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |                        (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);                    tailLen -= t;                    output[op++] = alphabet[(v >> 12) & 0x3f];                    output[op++] = alphabet[(v >> 6) & 0x3f];                    output[op++] = alphabet[v & 0x3f];                    if (do_padding) {                        output[op++] = '=';                    }                    if (do_newline) {                        if (do_cr) output[op++] = '\r';                        output[op++] = '\n';                    }                } else if (do_newline && op > 0 && count != LINE_GROUPS) {                    if (do_cr) output[op++] = '\r';                    output[op++] = '\n';                }                assert tailLen == 0;                assert p == len;            } else {                // Save the leftovers in tail to be consumed on the next                // call to encodeInternal.                if (p == len-1) {                    tail[tailLen++] = input[p];                } else if (p == len-2) {                    tail[tailLen++] = input[p];                    tail[tailLen++] = input[p+1];                }            }            this.op = op;            this.count = count;            return true;        }    }    private Base64() { }   // don't instantiate}

在这里插入图片描述
完美解决~

来源地址:https://blog.csdn.net/qq_41369057/article/details/131323360

--结束END--

本文标题: 安卓base64与其他语言base64算法还原出来差异问题???

本文链接: https://lsjlt.com/news/371466.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作