Base64编码与解码实现

2 篇文章 0 订阅
java中import sun.misc.BASE64Decoder;提示如下错误:

Access restriction: The type BASE64Decoder is not accessible due to restriction on required library

解决方法


可以使用Tomcat6.0中的org.apache.tomcat.util.buf.Base64类。

由于org.apache.tomcat.util.buf.Base64不支持中文的转码,于是在其基础上稍作了一些修改,具体代码如下:

 

package com.ztools.mail;

public class Base64 {

    static private final int BASELENGTH = 255;
    static private final int LOOKUPLENGTH = 64;
    static private final int TWENTYFOURBITGROUP = 24;
    static private final int EIGHTBIT = 8;
    static private final int SIXTEENBIT = 16;
    static private final int FOURBYTE = 4;

    static private final byte PAD = (byte) '=';
    static private byte[] base64Alphabet = new byte[BASELENGTH];
    static private byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];

    static private final boolean ISDEBUG = true;

    static {

        for (int i = 0; i < BASELENGTH; i++) {
            base64Alphabet[i] = -1;
        }
        // A-Z 0-25
        for (int i = 'Z'; i >= 'A'; i--) {
            base64Alphabet[i] = (byte) (i - 'A');
        }
        // a-z 26-51
        for (int i = 'z'; i >= 'a'; i--) {
            base64Alphabet[i] = (byte) (i - 'a' + 26);
        }

        // 1-9 52-61
        for (int i = '9'; i >= '0'; i--) {
            base64Alphabet[i] = (byte) (i - '0' + 52);
        }

        base64Alphabet['+'] = 62;
        base64Alphabet['/'] = 63;

        for (int i = 0; i <= 25; i++)
            lookUpBase64Alphabet[i] = (byte) ('A' + i);

        for (int i = 26, j = 0; i <= 51; i++, j++)
            lookUpBase64Alphabet[i] = (byte) ('a' + j);

        for (int i = 52, j = 0; i <= 61; i++, j++)
            lookUpBase64Alphabet[i] = (byte) ('0' + j);

        lookUpBase64Alphabet[62] = (byte)'+';
        lookUpBase64Alphabet[63] = (byte)'/';
    }

    static boolean isBase64(byte octect) {
        // shall we ignore white space? JEFF??
        return (octect == PAD || base64Alphabet[octect] != -1);
    }

    static boolean isArrayByteBase64(byte[] arrayOctect) {
        int length = arrayOctect.length;
        if (length == 0)
            return false;
        for (int i = 0; i < length; i++) {
            if (Base64.isBase64(arrayOctect[i]) == false)
                return false;
        }
        return true;
    }

    /**
     * Encodes hex octects into Base64
     * 
     * @param binaryData
     *            Array containing binaryData
     * @return Encoded Base64 array
     */
    public static byte[] encode(byte[] binaryData) {
        int lengthDataBits = binaryData.length * EIGHTBIT;
        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
        byte encodedData[] = null;

        if (fewerThan24bits != 0) // data not divisible by 24 bit
            encodedData = new byte[(numberTriplets + 1) * 4];
        else
            // 16 or 8 bit
            encodedData = new byte[numberTriplets * 4];

        byte k = 0, l = 0, oldByte1 = 0, oldByte2 = 0, oldByte3 = 0;

        int encodedIndex = 0;
        int dataIndex = 0;
        int i = 0;
        for (i = 0; i < numberTriplets; i++) {

            dataIndex = i * 3;
            oldByte1 = binaryData[dataIndex];
            oldByte2 = binaryData[dataIndex + 1];
            oldByte3 = binaryData[dataIndex + 2];

            l = (byte) (oldByte2 & 0x0f);
            k = (byte) (oldByte1 & 0x03);

            // new bytes (three bytes to four bytes)
            encodedIndex = i * 4;
            encodedData[encodedIndex] = lookUpBase64Alphabet[oldByte1 >> 2 & 0x3f];
            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[(oldByte2 >> 4 & 0xf)
                    | (k << 4)];
            encodedData[encodedIndex + 2] = lookUpBase64Alphabet[(l << 2)
                    | (oldByte3 >> 6 & 0x3)];
            encodedData[encodedIndex + 3] = lookUpBase64Alphabet[oldByte3 & 0x3f];
        }

        // form integral number of 6-bit groups
        dataIndex = i * 3;
        encodedIndex = i * 4;
        if (fewerThan24bits == EIGHTBIT) {
            oldByte1 = binaryData[dataIndex];
            k = (byte) (oldByte1 & 0x03);
            encodedData[encodedIndex] = lookUpBase64Alphabet[oldByte1 >> 2 & 0x3f];
            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[k << 4];
            encodedData[encodedIndex + 2] = PAD;
            encodedData[encodedIndex + 3] = PAD;
        } else if (fewerThan24bits == SIXTEENBIT) {

            oldByte1 = binaryData[dataIndex];
            oldByte2 = binaryData[dataIndex + 1];
            l = (byte) (oldByte2 & 0x0f);
            k = (byte) (oldByte1 & 0x03);
            encodedData[encodedIndex] = lookUpBase64Alphabet[oldByte1 >> 2 & 0x3f];
            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[(oldByte2 >> 4 & 0xf)
                    | (k << 4)];
            encodedData[encodedIndex + 2] = lookUpBase64Alphabet[l << 2];
            encodedData[encodedIndex + 3] = PAD;
        }
        return encodedData;
    }

    public static String encode(String str) {
        byte[] binaryData = str.getBytes();
        return new String(encode(binaryData));
    }

    /**
     * Decodes Base64 data into octects
     * 
     * @param base64Data
     *            Byte array containing Base64 data
     * @return Array containind decoded data.
     */
    public static byte[] decode(byte[] base64Data) {
        int numberQuadruple = base64Data.length / FOURBYTE;
        byte decodedData[] = null;
        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;

        // Throw away anything not in base64Data
        // Adjust size

        int encodedIndex = 0;
        int dataIndex = 0;
        decodedData = new byte[numberQuadruple * 3 + 1];

        for (int i = 0; i < numberQuadruple; i++) {
            dataIndex = i * 4;
            marker0 = base64Data[dataIndex + 2];
            marker1 = base64Data[dataIndex + 3];

            b1 = base64Alphabet[base64Data[dataIndex]];
            b2 = base64Alphabet[base64Data[dataIndex + 1]];

            if (marker0 != PAD && marker1 != PAD) { // No PAD e.g 3cQl
                b3 = base64Alphabet[marker0];
                b4 = base64Alphabet[marker1];

                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
                decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
            } else if (marker0 == PAD) { // Two PAD e.g. 3c[Pad][Pad]
                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                decodedData[encodedIndex + 1] = (byte) ((b2 & 0xf) << 4);
                decodedData[encodedIndex + 2] = (byte) 0;
            } else if (marker1 == PAD) { // One PAD e.g. 3cQ[Pad]
                b3 = base64Alphabet[marker0];

                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
                decodedData[encodedIndex + 2] = (byte) (b3 << 6);
            }
            encodedIndex += 3;
        }

        // NNN000 to NNN (clear end zero)
        int retDateLength = decodedData.length;
        for (int i = retDateLength - 1; i >= 0; i--) {
            if (0 != decodedData[i]) {
                break;
            }
            retDateLength--;
        }

        byte[] retDate = new byte[retDateLength];
        System.arraycopy(decodedData, 0, retDate, 0, retDateLength);
        return retDate;

    }

    public static String decode(String base64String) {
        char[] cs = base64String.toCharArray();
        byte[] bs = new byte[cs.length];

        for (int i = 0; i < cs.length; i++) {
            bs[i] = (byte) cs[i];
        }
        return new String(decode(bs));
    }

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

    public static String base64Decode(String orig) {
        char chars[] = orig.toCharArray();
        StringBuffer sb = new StringBuffer();
        int i = 0;

        int shift = 0; // # of excess bits stored in accum
        int acc = 0;

        for (i = 0; i < chars.length; i++) {
            int v = base64[chars[i] & 0xFF];

            if (v >= 64) {
                if (chars[i] != '=')
                    if (ISDEBUG)
                        System.out
                                .println(("Wrong char in base64: " + chars[i]));
            } else {
                acc = (acc << 6) | v;
                shift += 6;
                if (shift >= 8) {
                    shift -= 8;
                    sb.append((char) ((acc >> shift) & 0xff));
                }
            }
        }
        return sb.toString();
    }

}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Base64编码解码实现的C程序: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> const char BASE64_TABLE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char* base64_encode(const unsigned char* data, size_t input_length) { size_t output_length = 4 * ((input_length + 2) / 3); char* encoded_data = malloc(output_length + 1); if (encoded_data == NULL) return NULL; for (size_t i = 0, j = 0; i < input_length;) { uint32_t octet_a = i < input_length ? data[i++] : 0; uint32_t octet_b = i < input_length ? data[i++] : 0; uint32_t octet_c = i < input_length ? data[i++] : 0; uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; encoded_data[j++] = BASE64_TABLE[(triple >> 3 * 6) & 0x3F]; encoded_data[j++] = BASE64_TABLE[(triple >> 2 * 6) & 0x3F]; encoded_data[j++] = BASE64_TABLE[(triple >> 1 * 6) & 0x3F]; encoded_data[j++] = BASE64_TABLE[(triple >> 0 * 6) & 0x3F]; } for (size_t i = 0; i < input_length % 3; i++) { encoded_data[output_length - 1 - i] = '='; } encoded_data[output_length] = '\0'; return encoded_data; } unsigned char* base64_decode(const char* data, size_t input_length, size_t* output_length) { if (input_length % 4 != 0) return NULL; *output_length = input_length / 4 * 3; if (data[input_length - 1] == '=') (*output_length)--; if (data[input_length - 2] == '=') (*output_length)--; unsigned char* decoded_data = malloc(*output_length); if (decoded_data == NULL) return NULL; for (size_t i = 0, j = 0; i < input_length;) { uint32_t sextet_a = data[i] == '=' ? 0 & i++ : BASE64_TABLE[data[i++]]; uint32_t sextet_b = data[i] == '=' ? 0 & i++ : BASE64_TABLE[data[i++]]; uint32_t sextet_c = data[i] == '=' ? 0 & i++ : BASE64_TABLE[data[i++]]; uint32_t sextet_d = data[i] == '=' ? 0 & i++ : BASE64_TABLE[data[i++]]; uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF; if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF; } return decoded_data; } int main() { const char* input = "Hello, world!"; size_t input_length = strlen(input); char* encoded_data = base64_encode((const unsigned char*)input, input_length); printf("Encoded data: %s\n", encoded_data); size_t output_length; unsigned char* decoded_data = base64_decode(encoded_data, strlen(encoded_data), &output_length); printf("Decoded data: %s\n", decoded_data); free(encoded_data); free(decoded_data); return 0; } ``` 程序首先定义了一个Base64字符表,包含了所有可能的Base64字符。然后实现了两个函数,分别是Base64编码解码函数。 Base64编码函数将输入数据按照每3个字节一组进行处理,将每组字节转换成4个Base64字符。如果输入数据不是3的倍数,则在末尾加上相应数量的0字节,以使其能够被3整除。最后,函数将转换后的字符串末尾补上相应数量的=字符。 Base64解码函数将输入数据按照每4个字符一组进行处理,将每组字符转换成3个字节。如果末尾有=字符,则说明输入数据被填充了,需要在解码后去掉填充的0字节。 在程序中,我们将一个字符串进行Base64编码,然后再将编码后的字符串解码回原始字符串,最后输出结果。在输出解码后的数据时,我们将其当作一个字符串输出,可能会出现乱码,这是因为转换后的数据可能包含了0字节,而字符串输出函数会在遇到0字节时停止输出。如果需要输出二进制数据,应该使用fwrite函数来输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值