📄 base64.java
字号:
package com.mindprod.base64;
/**
* Encode arbitrary binary into printable ASCII using BASE64 encoding.
* <p/>
* Base64 is a way of encoding 8-bit characters using only ASCII printable characters similar to UUENCODE. UUENCODE
* includes a filename where BASE64 does not. The spec is described in RFC 2045. Base64 is a scheme where 3 bytes are
* concatenated, then split to form 4 groups of 6-bits each; and each 6-bits gets translated to an encoded printable
* ASCII character, via a table lookup. An encoded string is therefore longer than the original by about 1/3. The "="
* character is used to pad the end. Base64 is used, among other things, to encode the user:password string in an
* Authorization: header for HTTP. Don't confuse Base64 with x-www-form-urlencoded which is handled by
* Java.net.URLEncoder.encode/decode
* <p/>
* If you don't like this code, there is another implementation at http://www.ruffboy.com/download.htm Sun has an
* undocumented method called sun.misc.Base64Encoder.encode. You could use hex, simpler to code, but not as compact.
* <p/>
* If you wanted to encode a giant file, you could do it in large chunks that are even multiples of 3 bytes, except for
* the last chunk, and append the outputs.
* <p/>
* To encode a string, rather than binary data java.net.URLEncoder may be better. See printable characters in the Java
* glossary for a discussion of the differences.
* <p/>
* Base 64 armouring uses only the characters A-Z a-z 0-9 +/=. This makes it suitable for encoding binary data as SQL
* strings, that will work no matter what the encoding. Unfortunately + / and = all have special meaning in URLs.
* <pre>
* Freeware from:
* Roedy Green
* Canadian Mind Products
* #101 - 2536 Wark Street
* Victoria, BC Canada V8T 4G8
* tel:(250) 361-9093
* roedy g at mindprod dotcom
* <p/>
* Works exactly like Base64 except avoids using the characters
* + / and =. This means Base64u-encoded data can be used either
* URLCoded or plain in
* URL-Encoded contexts such as GET, PUT or URLs. You can treat the
* output either as
* not needing encoding or already URLEncoded.
* <p/>
* @version 1.9 2007-05-20
* </pre>
* <p/>
* Base64 ASCII armouring.
* <p/>
* copyright (c) 1999-2008 Roedy Green, Canadian Mind Products may be copied and used freely for any purpose but
* military.
* <p/>
* <p/>
* Encode arbitrary binary into printable ASCII using BASE64 encoding. very loosely based on the Base64 Reader by: Dr.
* Mark Thornton<br> Optrak Distribution Software Ltd. http://www.optrak.co.uk and Kevin Kelley's
* http://www.ruralnet.net/~kelley/java/Base64.java<br>
* <p/>
* version history vension 1.9, 2007-05-20 -- add icon and pad version 1.8, 2007-03-15 -- tidy. version 1.7 2007-03-15
* -- add Example version 1.4 2002 February 15 -- correct bugs with uneven line lengths, allow you to configure line
* separator. now need Base64 object and instance methods. new mailing address.
* <p/>
* version 1.3 2000-09-12 -- fix problems with estimating output length in encode
* <p/>
* version 1.2 2000-09-09 -- now handles decode as well.
* <p/>
* version 1.1 1999-12-04 -- more symmetrical encoding algorithm. more accurate StringBuffer allocation size.
* <p/>
* version 1.0 1999-12-03 -- posted in comp.lang.java.programmer.
* <p/>
* TODO Streams or files.
*/
class Base64
{
// ------------------------------ FIELDS ------------------------------
/**
* used to disable test driver.
*
* @noinspection WeakerAccess
*/
protected static final boolean DEBUGGING = false;
/**
* when package was released.
*
* @noinspection UnusedDeclaration
*/
private static final String RELEASE_DATE = "2007-05-20";
/**
* name of package.
*
* @noinspection UnusedDeclaration
*/
private static final String TITLE_STRING = "Base64";
/**
* version of package.
*
* @noinspection UnusedDeclaration
*/
private static final String VERSION_STRING = "1.9";
/**
* Marker value for chars we just ignore, e.g. \n \r high ascii.
*
* @noinspection WeakerAccess
*/
protected static final int IGNORE = -1;
/**
* Marker for = trailing pad.
*
* @noinspection WeakerAccess
*/
protected static final int PAD = -2;
/**
* letter of the alphabet used to encode binary values 0..63
*
* @noinspection WeakerAccess
*/
protected static char[] vc;
/**
* binary value encoded by a given letter of the alphabet 0..63.
*
* @noinspection WeakerAccess
*/
protected static int[] cv;
/**
* how we separate lines, e.g. \n, \r\n, \r etc.
*
* @noinspection WeakerAccess
*/
protected String lineSeparator = System.getProperty( "line.separator" );
/**
* letter of the alphabet used to encode binary values 0..63, overridden in Base64u.
*
* @noinspection WeakerAccess
*/
protected char[] valueToChar;
/**
* special character 1, will be - in Base64u.
*
* @noinspection WeakerAccess
*/
protected char spec1 = '+';
/**
* special character 2, will be _ in Base64u.
*
* @noinspection WeakerAccess
*/
protected char spec2 = '/';
/**
* special character 3, will be * in Base64u.
*
* @noinspection WeakerAccess
*/
protected char spec3 = '=';
/**
* binary value encoded by a given letter of the alphabet 0..63, overridden in Base64u.
*
* @noinspection WeakerAccess
*/
protected int[] charToValue;
/**
* max chars per line, excluding lineSeparator. A multiple of 4.
*
* @noinspection WeakerAccess
*/
protected int lineLength = 72;
// -------------------------- PUBLIC STATIC METHODS --------------------------
/**
* debug display array as hex.
*
* @param b byte array to display.
* @noinspection WeakerAccess
*/
public static void show( byte[] b )
{
for ( int i = 0; i < b.length; i++ )
{
System.out.print( Integer.toHexString( b[ i ] & 0xff ) + " " );
}
System.out.println();
}
// -------------------------- PUBLIC INSTANCE METHODS --------------------------
/**
* constructor.
*
* @noinspection WeakerAccess
*/
public Base64()
{
spec1 = '+';
spec2 = '/';
spec3 = '=';
initTables();
}
/**
* decode a well-formed complete Base64 string back into an array of bytes. It must have an even multiple of 4 data
* characters (not counting \n), padded out with = as needed.
*
* @param s base64-encoded string
* @return plaintext as a byte array.
* @noinspection WeakerAccess,CanBeFinal
*/
public byte[] decode( String s )
{
// estimate worst case size of output array, no embedded newlines.
byte[] b = new byte[( s.length() / 4 ) * 3];
// tracks where we are in a cycle of 4 input chars.
int cycle = 0;
// where we combine 4 groups of 6 bits and take apart as 3 groups of 8.
int combined = 0;
// how many bytes we have prepared.
int j = 0;
// will be an even multiple of 4 chars, plus some embedded \n
int len = s.length();
int dummies = 0;
for ( int i = 0; i < len; i++ )
{
int c = s.charAt( i );
int value = ( c <= 255 ) ? charToValue[ c ] : IGNORE;
// there are two magic values PAD (=) and IGNORE.
switch ( value )
{
case IGNORE:
// e.g. \n, just ignore it.
break;
case PAD:
value = 0;
dummies++;
// deliberate fallthrough
default:
/* regular value character */
switch ( cycle )
{
case 0:
combined = value;
cycle = 1;
break;
case 1:
combined <<= 6;
combined |= value;
cycle = 2;
break;
case 2:
combined <<= 6;
combined |= value;
cycle = 3;
break;
case 3:
combined <<= 6;
combined |= value;
// we have just completed a cycle of 4 chars.
// the four 6-bit values are in combined in
// big-endian order
// peel them off 8 bits at a time working lsb to msb
// to get our original 3 8-bit bytes back
b[ j + 2 ] = ( byte ) combined;
combined >>>= 8;
b[ j + 1 ] = ( byte ) combined;
combined >>>= 8;
b[ j ] = ( byte ) combined;
j += 3;
cycle = 0;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -