package com.cn.sec.rsa;
import java.io.UnsupportedEncodingException;
public class Base64 {
/**
* Chunk size per RFC 2045 section 6.8.
*
* <p>The {@value} character limit does not count the trailing CRLF, but counts
* all other characters, including any equal signs.</p>
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a>
*/
static final int CHUNK_SIZE = 76;
/**
* Chunk separator per RFC 2045 section 2.1.
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
*/
static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes();
/**
* The base length.
*/
static final int BASELENGTH = 255;
/**
* Lookup length.
*/
static final int LOOKUPLENGTH = 64;
/**
* Used to calculate the number of bits in a byte.
*/
static final int EIGHTBIT = 8;
/**
* Used when encoding something which has fewer than 24 bits.
*/
static final int SIXTEENBIT = 16;
/**
* Used to determine how many bits data contains.
*/
static final int TWENTYFOURBITGROUP = 24;
/**
* Used to get the number of Quadruples.
*/
static final int FOURBYTE = 4;
/**
* Used to test the sign of a byte.
*/
static final int SIGN = -128;
/**
* Byte used to pad output.
*/
static final byte PAD = (byte) '=';
// Create arrays to hold the base64 characters and a
// lookup for base64 chars
private static byte[] base64Alphabet = new byte[BASELENGTH];
private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
// Populating the lookup and character arrays
static {
for (int i = 0; i < BASELENGTH; i++) {
base64Alphabet[i] = (byte) -1;
}
for (int i = 'Z'; i >= 'A'; i--) {
base64Alphabet[i] = (byte) (i - 'A');
}
for (int i = 'z'; i >= 'a'; i--) {
base64Alphabet[i] = (byte) (i - 'a' + 26);
}
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) '/';
}
private static boolean isBase64(byte octect) {
if (octect == PAD) {
return true;
} else if (base64Alphabet[octect] == -1) {
return false;
} else {
return true;
}
}
/**
* Tests a given byte array to see if it contains
* only valid characters within the Base64 alphabet.
*
* @param arrayOctect byte array to test
* @return true if all bytes are valid characters in the Base64
* alphabet or if the byte array is empty; false, otherwise
*/
public static boolean isArrayByteBase64(byte[] arrayOctect) {
arrayOctect = discardWhitespace(arrayOctect);
int length = arrayOctect.length;
if (length == 0) {
// shouldn't a 0 length array be valid base64 data?
// return false;
return true;
}
for (int i = 0; i < length; i++) {
if (!isBase64(arrayOctect[i])) {
return false;
}
}
return true;
}
/**
* Encodes binary data using the base64 algorithm but
* does not chunk the output.
*
* @param binaryData binary data to encode
* @return Base64 characters
*/
public static byte[] encodeBase64(byte[] binaryData) {
return encodeBase64(binaryData, false);
}
/**
* Encodes binary data using the base64 algorithm and chunks
* the encoded output into 76 character blocks
*
* @param binaryData binary data to encode
* @return Base64 characters chunked in 76 character blocks
*/
public static byte[] encodeBase64Chunked(byte[] binaryData) {
return encodeBase64(binaryData, true);
}
/**
* Decodes a byte[] containing containing
* characters in the Base64 alphabet.
*
* @param pArray A byte array containing Base64 character data
* @return a byte array containing binary data
*/
public static byte[] decode(byte[] pArray) {
return decodeBase64(pArray);
}
/**
* Encodes binary data using the base64 algorithm, optionally
* chunking the output into 76 character blocks.
*
* @param binaryData Array containing binary data to encode.
* @param isChunked if isChunked is true this encoder will chunk
* the base64 output into 76 character blocks
* @return Base64-encoded data.
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
int lengthDataBits = binaryData.length * EIGHTBIT;
int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
byte encodedData[] = null;
int encodedDataLength = 0;
int nbrChunks = 0;
if (fewerThan24bits != 0) {
//data not divisible by 24 bit
encodedDataLength = (numberTriplets + 1) * 4;
} else {
// 16 or 8 bit
encodedDataLength = numberTriplets * 4;
}
// If the output is to be "chunked" into 76 character sections,
// for compliance with RFC 2045 MIME, then it is important to
// allow for extra length to account for the separator(s)
if (isChunked) {
nbrChunks =
(CHUNK_SEPARATOR.length == 0 ? 0 : (int) Math.ceil((float) encodedDataLength / CHUNK_SIZE));
encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length;
}
encodedData = new byte[encodedDataLength];
byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
int encodedIndex = 0;
int dataIndex = 0;
int i = 0;
int nextSeparatorIndex = CHUNK_SIZE;
int chunksSoFar = 0;
//log.debug("number of triplets = " + numberTriplets);
for (i = 0; i < numberTriplets; i++) {
dataIndex = i * 3;
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1];
b3 = binaryData[dataIndex + 2];
//log.debug("b1= " + b1 +", b2= " + b2 + ", b3= " + b3);
l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03);
byte val1 =
((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
byte val2 =
((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
byte val3 =
((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
//log.debug( "val2 = " + val2 );
//log.debug( "k4 = " + (k<<4) );
//log.debug( "vak = " + (val2 | (k<<4)) );
encodedData[encodedIndex + 1] =
lookUpBase64Alphabet[val2 | (k << 4)];
encodedData[encodedIndex + 2] =
lookUpBase64Alphabet[(l << 2) | val3];
encodedData[encodedIndex + 3] = lookUpBase64Alphabet[b3 & 0x3f];
encodedIndex += 4;
// If we are chunking, let's put a chunk separator down.
if (isChunke
非对称加密和对称加密混合应用
需积分: 49 64 浏览量
2016-05-23
11:40:48
上传
评论 3
收藏 1.26MB RAR 举报
riapgypm
- 粉丝: 15
- 资源: 8