base 64 en java
Ce petit programme permet de faire la conversion (encodage ou decodage) d'une source de données en base64 en utilisant le langage java.
/**
* Title:
* Description: encoder et decode en base64
* class base64
*
* @author Isaac Mekueko
* @version 1.0
*/
public final class Base64 {
static private final byte PADDING = ( byte ) '=';
static private final int SIGN = -128;
static private byte [] Encodebase64Alphabet = new byte[64];
static private byte [] alphaDecode =new byte[256];
static {
for(int i=0;i<=25;i++)
Encodebase64Alphabet[i]=(byte)('A'+i);
for(int i=26,j=0;i<=51;i++,j++)
Encodebase64Alphabet[i]=(byte)('a'+j);
for(int i=52,j=0;i<=61;i++,j++)
Encodebase64Alphabet[i]=(byte)('0'+j);
Encodebase64Alphabet[62]=(byte)('+');
Encodebase64Alphabet[63]=(byte)('/');
// decode
for(int i=0;i<256;i++)
alphaDecode[i]=-1;
for(int i='A',j=0;i<='Z';i++,j++)
alphaDecode[i]=(byte)j;
for(int i='a',j=26;i<='z';i++,j++)
alphaDecode[i]=(byte)j;
for(int i='0',j=52;i<='9';i++,j++)
alphaDecode[i]=(byte)j;
alphaDecode['+']=62;
alphaDecode['/']=63;
}
/*****************************************
* encode array byte from 0-255 to base64
* @param array byte
* @return array byte
* ****************************************/
static public byte [] encode (byte [] DataByte){
int numberDataBit=DataByte.length*8;
int numberDataBitMODULO24=numberDataBit%24;
int numberDataBitBY24=numberDataBit/24;
byte []EncodeData=null;
if(numberDataBitMODULO24==0) EncodeData=new byte[numberDataBitBY24*4];
else EncodeData=new byte[(numberDataBitBY24+1)*4];
byte Rshift2_b1,High_b2,Rshift6_b3,b1,b2,b3 ,e2,e3,e4 ;
int IndexDataByte,IndexEncodeData,i;
for( i=0;i<numberDataBitBY24;i++){
IndexDataByte=3*i;
IndexEncodeData=4*i;
b1=DataByte[IndexDataByte];
b2=DataByte[IndexDataByte+1];
b3=DataByte[IndexDataByte+2];
Rshift2_b1=((b1&SIGN)==0) ? (byte)(b1>>2) : (byte)(b1>>>2);
High_b2=((b2&SIGN)==0) ? (byte)(b2>>4) : (byte)(b2>>>4);
Rshift6_b3=((b2&SIGN)==0) ? (byte)(b3>>6) : (byte)(b3>>>6);
e2=(byte)(((b1&0x3)<<4)|High_b2);
e3=(byte)(((b2&0xF)<<2)|Rshift6_b3);
e4=(byte)(b3&0x3F);
EncodeData[IndexEncodeData]= Encodebase64Alphabet[Rshift2_b1];
EncodeData[IndexEncodeData+1]=Encodebase64Alphabet[e2];
EncodeData[IndexEncodeData+2]=Encodebase64Alphabet[e3];
EncodeData[IndexEncodeData+3]=Encodebase64Alphabet[e4];
}//end for
IndexDataByte=3*i;
IndexEncodeData=4*i;
if(numberDataBitMODULO24==16){
b1=DataByte[IndexDataByte];
b2=DataByte[IndexDataByte+1];
Rshift2_b1=((b1&SIGN)==0) ? (byte)(b1>>2) : (byte)(b1>>>2);
High_b2=((b2&SIGN)==0) ? (byte)(b2>>4) : (byte)(b2>>>4);
e2=(byte)(((b1&0x3)<<4)|High_b2);
e3=(byte)((b2&0xF)<<2);
e4=PADDING;
EncodeData[IndexEncodeData]= Encodebase64Alphabet[Rshift2_b1];
EncodeData[IndexEncodeData+1]=Encodebase64Alphabet[e2];
EncodeData[IndexEncodeData+2]=Encodebase64Alphabet[e3];
EncodeData[IndexEncodeData+3]=e4;
} else
if(numberDataBitMODULO24==8)
{
b1=DataByte[IndexDataByte];
Rshift2_b1=((b1&SIGN)==0) ? (byte)(b1>>2) : (byte)(b1>>>2);
e2=(byte)((b1&0x3)<<4);
e3=PADDING;
e4=PADDING;
EncodeData[IndexEncodeData]= Encodebase64Alphabet[Rshift2_b1];
EncodeData[IndexEncodeData+1]=Encodebase64Alphabet[e2];
EncodeData[IndexEncodeData+2]=e3;
EncodeData[IndexEncodeData+3]=e4;
}
return EncodeData;
}
/**************************************
* encode string from 0-255 to base64
* @param string
* @return String
* *************************************/
static public String encode(String str){
return new String(encode(str.getBytes()));
}
/**********************************************
* decode array byte from base64 to char 0-255
* @param array byte
* @return array byte
*********************************************/
public static byte[] decode(byte []DataByte){
if(!isByteInBase64(DataByte))return null;
int numberDataBit=DataByte.length*6;
int numberGroup_3bit=numberDataBit/24;
byte []DecodeData=null;
byte b1,b2,b3,b4,d1,d2,d3,ch1,ch2,ch3,ch4;
ch3=DataByte[DataByte.length-2];
ch4=DataByte[DataByte.length-1];
if(ch3!=PADDING&&ch4!=PADDING)
DecodeData=new byte[numberGroup_3bit*3];
else if(ch3==PADDING)
DecodeData=new byte[(numberGroup_3bit*3)-2];
else if(ch4==PADDING)
DecodeData=new byte[(numberGroup_3bit*3)-1];
int decodeIndex,encodeIndex;
for(int i=0; i<numberGroup_3bit;i++){
decodeIndex=3*i;
encodeIndex=4*i;
ch1=DataByte[encodeIndex];
ch2=DataByte[encodeIndex+1];
ch3=DataByte[encodeIndex+2];
ch4=DataByte[encodeIndex+3];
b1=alphaDecode[ch1];
b2=alphaDecode[ch2];
b3=alphaDecode[ch3];
b4=alphaDecode[ch4];
if(ch3!=PADDING&&ch4!=PADDING){
d1=(byte)((b1<<2)|(b2>>>4));
d2=(byte)((b2<<4)|(b3>>2));
d3=(byte)((b3<<6)|b4);
DecodeData[decodeIndex]=d1;
DecodeData[decodeIndex+1]=d2;
DecodeData[decodeIndex+2]=d3;
}else
if(ch3==PADDING){// 1 char
d1=(byte)((b1<<2)|(b2>>>4));
DecodeData[decodeIndex]=d1;
}
else
if(ch4==PADDING){ // 2char
d1=(byte)((b1<<2)|(b2>>>4));
d2=(byte)((b2<<4)|(b3>>2));
DecodeData[decodeIndex]=d1;
DecodeData[decodeIndex+1]=d2;
}
}//end for
return DecodeData;
}
/**
* decode base64 string into characters from 0-255
* @param string
* return string
**/
public static String decode(String str){
return new String(decode(str.getBytes()));
}
/**
* check if the byte belong to The Base64 Alphabet
* @param octet
* @return bolean value
* */
private static boolean isByteInBase64(byte octet){
if(octet==PADDING||alphaDecode[octet]!=-1) return true;
else
return false;
}
private static boolean isByteInBase64(byte []arraybyte){
int len=arraybyte.length;
for(int i=0;i<len;i++){
if(!isByteInBase64(arraybyte[i]))
return false;
}
return true;
}
}
José a rencontré quelques soucis dans son implementation et nous propose sa version de la méthode encode. Au passage il a adapté pour formatter en lignes de 19 quartets compatible envoie par mail.
public byte [] encode (byte [] DataByte)throws Exception{
int numberDataBit=DataByte.length*8;
int numberDataBitMODULO24=numberDataBit%24;
int numberDataBitBY24=numberDataBit/24;
int nrQuad=numberDataBitBY24;
if (numberDataBitMODULO24!=0) nrQuad++;
int nrlig=(nrQuad>0) ? (nrQuad-1)/19 : 0;
byte []EncodeData=new byte[nrQuad*4+nrlig*2];
byte Rshift2_b1,High_b2,Rshift6_b3,b1,b2,b3 ,e2,e3,e4 ;
int IndexDataByte,IndexEncodeData,i;
IndexDataByte=0;
IndexEncodeData=0;
nrQuad=0;
for( i=0;i<numberDataBitBY24;i++){
if(nrQuad==19)
{
EncodeData[IndexEncodeData]=(byte)'\r';
EncodeData[IndexEncodeData+1]=(byte)'\n';
IndexEncodeData += 2;
nrQuad=0;
}
b1=DataByte[IndexDataByte];
b2=DataByte[IndexDataByte+1];
b3=DataByte[IndexDataByte+2];
Rshift2_b1=(byte)((b1>>>2) & 0x3F);
High_b2=(byte)((b2>>>4) & 0x0F);
Rshift6_b3=(byte)((b3>>>6) & 0x03);
e2=(byte)(((b1&0x3)<<4)|High_b2);
e3=(byte)(((b2&0xF)<<2)|Rshift6_b3);
e4=(byte)(b3&0x3F);
EncodeData[IndexEncodeData]= Encodebase64Alphabet[Rshift2_b1];
EncodeData[IndexEncodeData+1]=Encodebase64Alphabet[e2];
EncodeData[IndexEncodeData+2]=Encodebase64Alphabet[e3];
EncodeData[IndexEncodeData+3]=Encodebase64Alphabet[e4];
IndexDataByte += 3;
IndexEncodeData += 4;
nrQuad++;
}//end for
if(numberDataBitMODULO24==16){
if(nrQuad==19)
{
EncodeData[IndexEncodeData]=(byte)'\r';
EncodeData[IndexEncodeData+1]=(byte)'\n';
IndexEncodeData += 2;
}
b1=DataByte[IndexDataByte];
b2=DataByte[IndexDataByte+1];
Rshift2_b1=((b1&SIGN)==0) ? (byte)(b1>>2) : (byte)(b1>>>2);
High_b2=((b2&SIGN)==0) ? (byte)(b2>>4) : (byte)(b2>>>4);
e2=(byte)(((b1&0x3)<<4)|High_b2);
e3=(byte)((b2&0xF)<<2);
e4=PADDING;
EncodeData[IndexEncodeData]= Encodebase64Alphabet[Rshift2_b1];
EncodeData[IndexEncodeData+1]=Encodebase64Alphabet[e2];
EncodeData[IndexEncodeData+2]=Encodebase64Alphabet[e3];
EncodeData[IndexEncodeData+3]=e4;
} else
if(numberDataBitMODULO24==8)
{
if(nrQuad==19)
{
EncodeData[IndexEncodeData]=(byte)'\r';
EncodeData[IndexEncodeData+1]=(byte)'\n';
IndexEncodeData += 2;
}
b1=DataByte[IndexDataByte];
Rshift2_b1=((b1&SIGN)==0) ? (byte)(b1>>2) : (byte)(b1>>>2);
e2=(byte)((b1&0x3)<<4);
e3=PADDING;
e4=PADDING;
EncodeData[IndexEncodeData]= Encodebase64Alphabet[Rshift2_b1];
EncodeData[IndexEncodeData+1]=Encodebase64Alphabet[e2];
EncodeData[IndexEncodeData+2]=e3;
EncodeData[IndexEncodeData+3]=e4;
}
return EncodeData;
}
et la méthode
public static String decode(String str){
return new String(decode(str.getBytes()));
}
peut avantageusement être écrite
public static String decode(String str){
return new String(decode(str.getBytes("ISO-8859-1")));
}
dans les cas où c'est nécessaire (si String est une donnée binaire)
|