解码 base64 字符串 Java 5
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/917604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Decode base64 String Java 5
提问by
Is there a straight forward way to decode a base64 string using ONLY THE JAVA 1.5 LIBRARIES?
是否有直接使用 JAVA 1.5 库解码 base64 字符串的直接方法?
I have to use Java 1.5 due to cross platform compatibility issues between Windows and Mac OS X (only Mac 10.5 supports Java 1.6, everything lower than 10.5 has Java 1.5 as default).
由于 Windows 和 Mac OS X 之间的跨平台兼容性问题,我必须使用 Java 1.5(只有 Mac 10.5 支持 Java 1.6,低于 10.5 的所有版本都默认使用 Java 1.5)。
The object "sun.misc.Base64Decoder" exists in Java 6, but not in Java 5.
对象“sun.misc.Base64Decoder”存在于 Java 6 中,但不存在于 Java 5 中。
采纳答案by Jon
No, it's not possible based on just using JDK 5.0.
不,仅使用 JDK 5.0 是不可能的。
You'll need to roll your own implementation (it isn't that hard) or preferably use one of the open source implementations. There are lots including Commons Codec which provides Base64 http://commons.apache.org/codec/api-release/org/apache/commons/codec/binary/Base64.html
您需要推出自己的实现(这并不难),或者最好使用开源实现之一。有很多包括提供 Base64 的 Commons Codec http://commons.apache.org/codec/api-release/org/apache/commons/codec/binary/Base64.html
JavaMail also provides Base64 encoding/decoding via MimeUtility which also does quoted printable encoding etc...
JavaMail 还通过 MimeUtility 提供 Base64 编码/解码,它也提供引用的可打印编码等...
http://java.sun.com/products/javamail/javadocs/javax/mail/internet/MimeUtility.html
http://java.sun.com/products/javamail/javadocs/javax/mail/internet/MimeUtility.html
回答by Clint
Just use http://iharder.sourceforge.net/current/java/base64/. It is in the public domain. So you can just drop the code into your project without worrying about license issues or including other jars. The class you are looking for is not in JDK 1.5.
只需使用http://iharder.sourceforge.net/current/java/base64/。它属于公共领域。因此,您可以将代码放入您的项目中,而无需担心许可证问题或包含其他 jar。您要查找的类不在 JDK 1.5 中。
回答by Andre Miller
There are also various implementations on this page: http://www.rgagnon.com/javadetails/java-0598.html
这个页面上也有各种实现:http: //www.rgagnon.com/javadetails/java-0598.html
回答by Jherico
FYI, you should be using this even in Java 6. Don't use classes in sun.*
仅供参考,即使在 Java 6 中你也应该使用它。 不要在 sun 中使用类。*
回答by Lawrence Dol
Here's my version - it should be completely standalone:
这是我的版本 - 它应该是完全独立的:
public class Base64
{
// *****************************************************************************
// INSTANCE PROPERTIES
// *****************************************************************************
private String lineSeparator;
private int lineLength;
// *****************************************************************************
// INSTANCE CONSTRUCTION/INITIALIZATON/FINALIZATION, OPEN/CLOSE
// *****************************************************************************
public Base64() {
lineSeparator=System.getProperty("line.separator");
lineLength=0;
}
// *****************************************************************************
// INSTANCE METHODS
// *****************************************************************************
public String encode(byte[] bin) {
return encode(bin,0,bin.length);
}
/**
* Encode an array of bytes as Base64.
* It will be broken into lines if the line length is not 0. If broken into lines,
* the last line is not terminated with a line separator.
*
* param ba The byte array to encode.
*/
public String encode(byte[] bin, int str, int len) {
int ol; // output length
StringBuffer sb; // string buffer for output(must be local for recursion to work).
int lp; // line position(must be local for recursion to work).
int el; // even multiple of 3 length
int ll; // leftover length
// CREATE OUTPUT BUFFER
ol=(((len+2)/3)*4);
if(lineLength!=0) {
int lines=(((ol+lineLength-1)/lineLength)-1);
if(lines>0) { ol+=(lines*lineSeparator.length()); }
}
sb=new StringBuffer(ol);
lp=0;
// EVEN MULTIPLES OF 3
el=(len/3)*3;
ll=(len-el);
for(int xa=0; xa<el; xa+=3) {
int cv;
int c0,c1,c2,c3;
if(lineLength!=0) {
lp+=4;
if(lp>lineLength) { sb.append(lineSeparator); lp=4; }
}
// get next three bytes in unsigned form lined up, in big-endian order
cv =(bin[xa+str+0]&0xFF); cv<<=8;
cv|=(bin[xa+str+1]&0xFF); cv<<=8;
cv|=(bin[xa+str+2]&0xFF);
// break those 24 bits into a 4 groups of 6 bits, working LSB to MSB.
c3=cv&0x3F; cv >>>=6;
c2=cv&0x3F; cv >>>=6;
c1=cv&0x3F; cv >>>=6;
c0=cv&0x3F;
// Translate into the equivalent alpha character emitting them in big-endian order.
sb.append(ENCODE[c0]);
sb.append(ENCODE[c1]);
sb.append(ENCODE[c2]);
sb.append(ENCODE[c3]);
}
// LEFTOVERS
if(lineLength!=0 && ll>0) {
lp+=4;
if(lp>lineLength) { sb.append(lineSeparator); lp=4; }
}
if(ll==1) {
sb.append(encode(new byte[] { bin[el+str], 0, 0 }).substring(0,2)).append("=="); // Use recursion so escaping logic is not repeated, replacing last 2 chars with "==".
}
else if(ll==2) {
sb.append(encode(new byte[] { bin[el+str], bin[el+str+1], 0 }).substring(0,3)).append("="); // Use recursion so escaping logic is not repeated, replacing last char and "=".
}
if(ol!=sb.length()) { throw new RuntimeException("Error in Base64 encoding method: Calculated output length of "+ol+" did not match actual length of "+sb.length()); }
return sb.toString();
}
public byte[] decode(String b64) {
return decode(b64,0,b64.length());
}
/**
* Decode a Base64 string to an array of bytes.
* The string must have a length evenly divisible by 4 (not counting line separators and other
* ignorable characters, like whitespace).
*/
public byte[] decode(String b64, int str, int len) {
byte[] ba; // target byte array
int dc; // decode cycle (within sequence of 4 input chars).
int rv; // reconstituted value
int ol; // output length
int pc; // padding count
ba=new byte[(len/4)*3]; // create array to largest possible size.
dc=0;
rv=0;
ol=0;
pc=0;
for(int xa=0; xa<len; xa++) {
int ch=b64.charAt(xa+str);
int value=(ch<=255 ? DECODE[ch] : IGNORE);
if(value!=IGNORE) {
if(value==PAD) {
value=0;
pc++;
}
switch(dc) {
case 0: {
rv=value;
dc=1;
} break;
case 1: {
rv<<=6;
rv|=value;
dc=2;
} break;
case 2: {
rv<<=6;
rv|=value;
dc=3;
} break;
case 3: {
rv<<=6;
rv|=value;
// Completed a cycle of 4 chars, so recombine the four 6-bit values in big-endian order
ba[ol+2]=(byte)rv; rv>>>=8;
ba[ol+1]=(byte)rv; rv>>>=8;
ba[ol]=(byte)rv; ol+=3;
dc=0;
} break;
}
}
}
if(dc!=0) {
throw new ArrayIndexOutOfBoundsException("Base64 data given as input was not an even multiple of 4 characters (should be padded with '=' characters).");
}
ol-=pc;
if(ba.length!=ol) {
byte[] b2=new byte[ol];
System.arraycopy(ba, 0, b2, 0, ol);
ba=b2;
}
return ba;
}
/**
* Set maximum line length for encoded lines.
* Ignored by decode.
* @param len Length of each line. 0 means no newlines inserted. Must be a multiple of 4.
*/
public void setLineLength(int len) {
this.lineLength=(len/4)*4;
}
/**
* Set the line separator sequence for encoded lines.
* Ignored by decode.
* Usually contains only a combination of chars \n and \r, but could be any chars except 'A'-'Z', 'a'-'z', '0'-'9', '+' and '/'.
* @param linsep Line separator - may be "" but not null.
*/
public void setLineSeparator(String linsep) {
this.lineSeparator=linsep;
}
// *****************************************************************************
// STATIC PROPERTIES
// *****************************************************************************
static private final char[] ENCODE=new char[64]; // translation array for encoding
static private final int[] DECODE=new int[256]; // translation array for decoding
static private final int IGNORE=-1; // flag for values to ignore when decoding
static private final int PAD=-2; // flag value for padding value when decoding
static private final Base64 BASE64=new Base64(); // default converter
// *****************************************************************************
// STATIC INIT & MAIN
// *****************************************************************************
static {
for(int xa=0; xa<=25; xa++) { ENCODE[xa]=(char)('A'+xa); } // 0..25 -> 'A'..'Z'
for(int xa=0; xa<=25; xa++) { ENCODE[xa+26]=(char)('a'+xa); } // 26..51 -> 'a'..'z'
for(int xa=0; xa<= 9; xa++) { ENCODE[xa+52]=(char)('0'+xa); } // 52..61 -> '0'..'9'
ENCODE[62]='+';
ENCODE[63]='/';
for(int xa=0; xa<256; xa++) { DECODE[xa]=IGNORE; } // set all chars to IGNORE, first
for(int xa=0; xa< 64; xa++) { DECODE[ENCODE[xa]]=xa; } // set the Base 64 chars to their integer byte values
DECODE['=']=PAD;
}
// *****************************************************************************
// STATIC METHODS
// *****************************************************************************
static public String toString(byte[] dta) {
return BASE64.encode(dta);
}
static public String toString(byte[] dta, int str, int len) {
return BASE64.encode(dta,str,len);
}
static public byte[] toBytes(String b64) {
return BASE64.decode(b64);
}
static public byte[] toBytes(String b64, int str, int len) {
return BASE64.decode(b64,str,len);
}
} // END PUBLIC CLASS