Android Open Source - kakao-android-sdk-standalone Base64






From Project

Back to project page kakao-android-sdk-standalone.

License

The source code is released under:

Apache License

If you think the Android project kakao-android-sdk-standalone listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * This class is a part of Base64 in Apach commons codec.
 */*  ww  w. ja va2  s . com*/
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.kakao.helper;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 *
 * @author MJ
 */
public class Base64 {
    private static final int BYTES_PER_UNENCODED_BLOCK = 3;
    private static final int BYTES_PER_ENCODED_BLOCK = 4;
    private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
    private static final int DEFAULT_BUFFER_SIZE = 8192;
    private static final int MASK_6BITS = 0x3f;
    private static final int EOF = -1;
    private static final int MIME_CHUNK_SIZE = 76;
    private static final byte[] CHUNK_SEPARATOR = {'\r', '\n'};
    private static final Charset UTF_8 = Charset.forName("UTF-8");

    private final int unencodedBlockSize;
    private final int encodedBlockSize;
    private final int lineLength;
    private final int chunkSeparatorLength;
    private static final byte PAD_DEFAULT = '=';
    private final byte PAD = PAD_DEFAULT;

    private final byte[] lineSeparator;
    @SuppressWarnings("unused")
    private final int decodeSize;
    private final int encodeSize;
    private final byte[] encodeTable;
    private final byte[] decodeTable = DECODE_TABLE;

    private static final byte[] DECODE_TABLE = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -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, 62, -1, 63, 52, 53, 54,
        55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -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
    };

    private static final byte[] STANDARD_ENCODE_TABLE = {
        '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[] URL_SAFE_ENCODE_TABLE = {
        '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', '-', '_'
    };

    static class Context {
        int ibitWorkArea;
        long lbitWorkArea;
        byte[] buffer;
        int pos;
        int readPos;
        boolean eof;
        int currentLinePos;
        int modulus;

        Context() {
        }

        public String toString() {
            return String.format("%s[buffer=%s, currentLinePos=%s, eof=%s, ibitWorkArea=%s, lbitWorkArea=%s, " +
                "modulus=%s, pos=%s, readPos=%s]", this.getClass().getSimpleName(), Arrays.toString(buffer),
                currentLinePos, eof, ibitWorkArea, lbitWorkArea, modulus, pos, readPos);
        }
    }


    private Base64(final boolean urlSafe) {
        this(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe);
    }

    private Base64(final int lineLength, final byte[] lineSeparator, final boolean urlSafe) {
        this.unencodedBlockSize = BYTES_PER_UNENCODED_BLOCK;
        this.encodedBlockSize = BYTES_PER_ENCODED_BLOCK;
        this.chunkSeparatorLength = lineSeparator == null ? 0 : lineSeparator.length;
        final boolean useChunking = lineLength > 0 && chunkSeparatorLength > 0;
        this.lineLength = useChunking ? (lineLength / encodedBlockSize) * encodedBlockSize : 0;

        if (lineSeparator != null) {
            if (containsAlphabetOrPad(lineSeparator)) {
                final String sep = newStringUtf8(lineSeparator);
                throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]");
            }
            if (lineLength > 0) {
                this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length;
                this.lineSeparator = new byte[lineSeparator.length];
                System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length);
            } else {
                this.encodeSize = BYTES_PER_ENCODED_BLOCK;
                this.lineSeparator = null;
            }
        } else {
            this.encodeSize = BYTES_PER_ENCODED_BLOCK;
            this.lineSeparator = null;
        }
        this.decodeSize = this.encodeSize - 1;
        this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
    }

    boolean containsAlphabetOrPad(final byte[] arrayOctet) {
        if (arrayOctet == null) {
            return false;
        }
        for (final byte element : arrayOctet) {
            if (PAD == element || isInAlphabet(element)) {
                return true;
            }
        }
        return false;
    }

    public static String encodeBase64URLSafeString(final byte[] binaryData) {
        return newStringUtf8(encodeBase64(binaryData, false, true));
    }

    private static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe) {
        return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE);
    }

    private static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked,
                                       final boolean urlSafe, final int maxResultSize) {
        if (binaryData == null || binaryData.length == 0) {
            return binaryData;
        }

        final Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe);
        final long len = b64.getEncodedLength(binaryData);
        if (len > maxResultSize) {
            throw new IllegalArgumentException("Input array too big, the output array would be bigger (" +
                len +
                ") than the specified maximum size of " +
                maxResultSize);
        }

        return b64.encode(binaryData);
    }

    byte[] encode(final byte[] pArray) {
        if (pArray == null || pArray.length == 0) {
            return pArray;
        }
        final Context context = new Context();
        encode(pArray, 0, pArray.length, context);
        encode(pArray, 0, EOF, context);
        final byte[] buf = new byte[context.pos - context.readPos];
        readResults(buf, 0, buf.length, context);
        return buf;
    }

    void encode(final byte[] in, int inPos, final int inAvail, final Context context) {
        if (context.eof) {
            return;
        }
        // inAvail < 0 is how we're informed of EOF in the underlying data we're
        // encoding.
        if (inAvail < 0) {
            context.eof = true;
            if (0 == context.modulus && lineLength == 0) {
                return; // no leftovers to process and not using chunking
            }
            final byte[] buffer = ensureBufferSize(encodeSize, context);
            final int savedPos = context.pos;
            switch (context.modulus) { // 0-2
                case 0: // nothing to do here
                    break;
                case 1: // 8 bits = 6 + 2
                    // top 6 bits:
                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 2) & MASK_6BITS];
                    // remaining 2:
                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 4) & MASK_6BITS];
                    // URL-SAFE skips the padding to further reduce size.
                    if (encodeTable == STANDARD_ENCODE_TABLE) {
                        buffer[context.pos++] = PAD;
                        buffer[context.pos++] = PAD;
                    }
                    break;

                case 2: // 16 bits = 6 + 6 + 4
                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 10) & MASK_6BITS];
                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 4) & MASK_6BITS];
                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 2) & MASK_6BITS];
                    // URL-SAFE skips the padding to further reduce size.
                    if (encodeTable == STANDARD_ENCODE_TABLE) {
                        buffer[context.pos++] = PAD;
                    }
                    break;
                default:
                    throw new IllegalStateException("Impossible modulus " + context.modulus);
            }
            context.currentLinePos += context.pos - savedPos; // keep track of current line position
            // if currentPos == 0 we are at the start of a line, so don't add CRLF
            if (lineLength > 0 && context.currentLinePos > 0) {
                System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length);
                context.pos += lineSeparator.length;
            }
        } else {
            for (int i = 0; i < inAvail; i++) {
                final byte[] buffer = ensureBufferSize(encodeSize, context);
                context.modulus = (context.modulus + 1) % BYTES_PER_UNENCODED_BLOCK;
                int b = in[inPos++];
                if (b < 0) {
                    b += 256;
                }
                context.ibitWorkArea = (context.ibitWorkArea << 8) + b; //  BITS_PER_BYTE
                if (0 == context.modulus) { // 3 bytes = 24 bits = 4 * 6 bits to extract
                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 18) & MASK_6BITS];
                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 12) & MASK_6BITS];
                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 6) & MASK_6BITS];
                    buffer[context.pos++] = encodeTable[context.ibitWorkArea & MASK_6BITS];
                    context.currentLinePos += BYTES_PER_ENCODED_BLOCK;
                    if (lineLength > 0 && lineLength <= context.currentLinePos) {
                        System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length);
                        context.pos += lineSeparator.length;
                        context.currentLinePos = 0;
                    }
                }
            }
        }
    }

    byte[] ensureBufferSize(final int size, final Context context) {
        if ((context.buffer == null) || (context.buffer.length < context.pos + size)) {
            return resizeBuffer(context);
        }
        return context.buffer;
    }

    int readResults(final byte[] b, final int bPos, final int bAvail, final Context context) {
        if (context.buffer != null) {
            final int len = Math.min(available(context), bAvail);
            System.arraycopy(context.buffer, context.readPos, b, bPos, len);
            context.readPos += len;
            if (context.readPos >= context.pos) {
                context.buffer = null; // so hasData() will return false, and this method can return -1
            }
            return len;
        }
        return context.eof ? EOF : 0;
    }

    int available(final Context context) {  // package protected for access from I/O streams
        return context.buffer != null ? context.pos - context.readPos : 0;
    }

    private byte[] resizeBuffer(final Context context) {
        if (context.buffer == null) {
            context.buffer = new byte[getDefaultBufferSize()];
            context.pos = 0;
            context.readPos = 0;
        } else {
            final byte[] b = new byte[context.buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR];
            System.arraycopy(context.buffer, 0, b, 0, context.buffer.length);
            context.buffer = b;
        }
        return context.buffer;
    }

    int getDefaultBufferSize() {
        return DEFAULT_BUFFER_SIZE;
    }


    long getEncodedLength(final byte[] pArray) {
        long len = ((pArray.length + unencodedBlockSize - 1) / unencodedBlockSize) * (long) encodedBlockSize;
        if (lineLength > 0) {
            len += ((len + lineLength - 1) / lineLength) * chunkSeparatorLength;
        }
        return len;
    }

    private static String newStringUtf8(final byte[] bytes) {
        return newString(bytes, UTF_8);
    }

    private static String newString(final byte[] bytes, final Charset charset) {
        try {
            return bytes == null ? null : new String(bytes, charset.name());
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

    boolean isInAlphabet(final byte octet) {
        return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1;
    }
}




Java Source Code List

com.kakao.APIErrorResult.java
com.kakao.AppActionBuilder.java
com.kakao.ErrorCode.java
com.kakao.KakaoLinkParseException.java
com.kakao.KakaoLink.java
com.kakao.KakaoStoryHttpResponseHandler.java
com.kakao.KakaoStoryPostParamBuilder.java
com.kakao.KakaoStoryProfile.java
com.kakao.KakaoStoryService.java
com.kakao.KakaoStoryUpload.java
com.kakao.KakaoTalkHttpResponseHandler.java
com.kakao.KakaoTalkLinkMessageBuilder.java
com.kakao.KakaoTalkProfile.java
com.kakao.KakaoTalkService.java
com.kakao.LoginActivity.java
com.kakao.LogoutResponseCallback.java
com.kakao.MeResponseCallback.java
com.kakao.SessionCallback.java
com.kakao.Session.java
com.kakao.SignupResponseCallback.java
com.kakao.UnlinkResponseCallback.java
com.kakao.UpdateProfileResponseCallback.java
com.kakao.UserManagement.java
com.kakao.UserProfileResponseCallback.java
com.kakao.UserProfile.java
com.kakao.UserResponseCallback.java
com.kakao.User.java
com.kakao.authorization.AuthorizationResult.java
com.kakao.authorization.Authorizer.java
com.kakao.authorization.accesstoken.AccessTokenRequest.java
com.kakao.authorization.accesstoken.AccessToken.java
com.kakao.authorization.accesstoken.GetterAccessToken.java
com.kakao.authorization.accesstoken.package-info.java
com.kakao.authorization.authcode.AuthorizationCodeHandler.java
com.kakao.authorization.authcode.AuthorizationCodeRequest.java
com.kakao.authorization.authcode.AuthorizationCode.java
com.kakao.authorization.authcode.GetterAuthorizationCode.java
com.kakao.authorization.authcode.KakaoWebViewDialog.java
com.kakao.authorization.authcode.LoggedInTalkAuthHandler.java
com.kakao.authorization.authcode.LoggedOutTalkAuthHandler.java
com.kakao.authorization.authcode.OnWebViewCompleteListener.java
com.kakao.authorization.authcode.WebViewAuthHandler.java
com.kakao.authorization.authcode.package-info.java
com.kakao.exception.KakaoException.java
com.kakao.exception.KakaoWebviewException.java
com.kakao.exception.package-info.java
com.kakao.helper.Base64.java
com.kakao.helper.JsonHelper.java
com.kakao.helper.Logger.java
com.kakao.helper.ServerProtocol.java
com.kakao.helper.SharedPreferencesCache.java
com.kakao.helper.SystemInfo.java
com.kakao.helper.TalkProtocol.java
com.kakao.helper.Utility.java
com.kakao.helper.package-info.java
com.kakao.http.AsyncHttpClient.java
com.kakao.http.BodyPart.java
com.kakao.http.FilePart.java
com.kakao.http.HttpRequestBuilder.java
com.kakao.http.HttpRequestTask.java
com.kakao.http.HttpResponseHandler.java
com.kakao.http.HttpTaskManager.java
com.kakao.http.KakaoAsyncHandler.java
com.kakao.http.Multipart.java
com.kakao.http.Request.java
com.kakao.http.Response.java
com.kakao.http.package-info.java
com.kakao.internal.ActionInfo.java
com.kakao.internal.Action.java
com.kakao.internal.KakaoTalkLinkProtocol.java
com.kakao.internal.LinkObject.java
com.kakao.internal.package-info.java
com.kakao.rest.APIHttpRequestTask.java
com.kakao.rest.package-info.java
com.kakao.sample.kakaolink.KakaoLinkMainActivity.java
com.kakao.sample.kakaolink.KakaoLinkSplashActivity.java
com.kakao.sample.kakaolink.package-info.java
com.kakao.sample.kakaostory.KakaoStoryLoginActivity.java
com.kakao.sample.kakaostory.KakaoStoryMainActivity.java
com.kakao.sample.kakaostory.KakaoStorySignupActivity.java
com.kakao.sample.kakaostory.package-info.java
com.kakao.sample.kakaotalk.KakaoTalkLoginActivity.java
com.kakao.sample.kakaotalk.KakaoTalkMainActivity.java
com.kakao.sample.kakaotalk.KakaoTalkSignupActivity.java
com.kakao.sample.kakaotalk.package-info.java
com.kakao.sample.usermgmt.ExtraUserPropertyLayout.java
com.kakao.sample.usermgmt.UserMgmtLoginActivity.java
com.kakao.sample.usermgmt.UsermgmtMainActivity.java
com.kakao.sample.usermgmt.UsermgmtSignupActivity.java
com.kakao.sample.usermgmt.package-info.java
com.kakao.template.loginbase.SampleLoginActivity.java
com.kakao.template.loginbase.SampleSignupActivity.java
com.kakao.template.loginbase.package-info.java
com.kakao.template.loginfree.LoginFreeTemplateActivity.java
com.kakao.template.loginfree.package-info.java
com.kakao.widget.LoginButton.java
com.kakao.widget.ProfileLayout.java
com.kakao.widget.package-info.java
com.kakao.package-info.java