All Downloads are FREE. Search and download functionalities are using the official Maven repository.

inti.util.Base64Util Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2012 the project-owners
 *
 *    Licensed 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 inti.util;

import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * An utility for fast Base64 decoding - not thread-safe.
 */
public class Base64Util {
    
    /**
     * Transfer-buffer.
     */
    byte[] chars = new byte[4];
    /**
     * base64 alphabet for decoding.
     */
    byte[] alphabet;
    
    /**
     * Initializes with {@link Base64OutputByteBuffer#DEFAULT_ALPHABET}.
     */
    public Base64Util() {
        alphabet = decodeAlphabet(Base64OutputByteBuffer.DEFAULT_ALPHABET);
    }
    
    /**
     * Initializes with the given alphabet.
     */
    public Base64Util(String alphabet) {
        this.alphabet = decodeAlphabet(alphabet);
    }
    
    /**
     * Transforms the given alphabet into a more efficient byte-array version.
     * 
     * @param str
     * @return
     */
    byte[] decodeAlphabet(String str) {
        byte[] result = new byte[256];
        int index = 0;
        
        Arrays.fill(result, (byte) -1);
        for (char letter : str.toCharArray()) {
            result[letter] = (byte) index++;
        }
        
        return result;
    }
    
    /**
     * Decodes the base64 string into the {@link ByteBuffer} without any object allocations.
     * 
     * @param source
     * @param buffer
     */
    public void decodeBase64(String source, ByteBuffer buffer) {
        int index = 0, end = source.length() - 4;
        
        for (; index < end; index += 4) {
            chars[0] = alphabet[source.charAt(index)];
            chars[1] = alphabet[source.charAt(index + 1)];
            chars[2] = alphabet[source.charAt(index + 2)];
            chars[3] = alphabet[source.charAt(index + 3)];
            
            buffer.put((byte) (chars[0] << 2 | chars[1] >> 4));
            buffer.put((byte) ((chars[1] & 15) << 4 | chars[2] >> 2));
            buffer.put((byte) ((chars[2] & 3) << 6 | chars[3]));
        }
        
        chars[0] = alphabet[source.charAt(index)];
        chars[1] = alphabet[source.charAt(index + 1)];
        chars[2] = alphabet[source.charAt(index + 2)];
        chars[3] = alphabet[source.charAt(index + 3)];
        
        buffer.put((byte) (chars[0] << 2 | chars[1] >> 4));
        if (chars[2] != -1) {
            buffer.put((byte) ((chars[1] & 15) << 4 | chars[2] >> 2));
        }
        if (chars[3] != -1) {
            buffer.put((byte) ((chars[2] & 3) << 6 | chars[3]));
        }
    }
    
    /**
     * Decodes the base64 source buffer into the dest-{@link ByteBuffer} without any object allocations.
     * 
     * @param source
     * @param length
     * @param dest
     */
    public void decodeBase64(ByteBuffer source, int length, ByteBuffer dest) {
        int index = 0, end = length - 4;
        
        for (; index < end && source.position() < source.limit() - 4; index += 4) {
            chars[0] = alphabet[source.get()];
            chars[1] = alphabet[source.get()];
            chars[2] = alphabet[source.get()];
            chars[3] = alphabet[source.get()];
            
            dest.put((byte) (chars[0] << 2 | chars[1] >> 4));
            dest.put((byte) ((chars[1] & 15) << 4 | chars[2] >> 2));
            dest.put((byte) ((chars[2] & 3) << 6 | chars[3]));
        }
        
        chars[0] = alphabet[source.get()];
        chars[1] = alphabet[source.get()];
        chars[2] = alphabet[source.get()];
        chars[3] = alphabet[source.get()];
        
        dest.put((byte) (chars[0] << 2 | chars[1] >> 4));
        if (chars[2] != -1) {
            dest.put((byte) ((chars[1] & 15) << 4 | chars[2] >> 2));
        }
        if (chars[3] != -1) {
            dest.put((byte) ((chars[2] & 3) << 6 | chars[3]));
        }
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy