moved B64Code to util
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2399 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
5d5ec1f0f6
commit
c76886e2aa
|
@ -18,9 +18,9 @@ import java.io.IOException;
|
|||
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
import org.eclipse.jetty.http.HttpHeaders;
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.ByteArrayBuffer;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,9 +18,9 @@ import java.io.IOException;
|
|||
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
import org.eclipse.jetty.http.HttpHeaders;
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.ByteArrayBuffer;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 1999-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -11,339 +11,18 @@
|
|||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
|
||||
package org.eclipse.jetty.http.security;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/** Fast B64 Encoder/Decoder as described in RFC 1421.
|
||||
* <p>Does not insert or interpret whitespace as described in RFC
|
||||
* 1521. If you require this you must pre/post process your data.
|
||||
* <p> Note that in a web context the usual case is to not want
|
||||
* linebreaks or other white space in the encoded output.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class B64Code
|
||||
{
|
||||
// ------------------------------------------------------------------
|
||||
static final char pad='=';
|
||||
static final char[] rfc1421alphabet=
|
||||
{
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
|
||||
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
|
||||
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
|
||||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
|
||||
};
|
||||
|
||||
static final byte[] rfc1421nibbles;
|
||||
|
||||
static
|
||||
{
|
||||
rfc1421nibbles=new byte[256];
|
||||
for (int i=0;i<256;i++)
|
||||
rfc1421nibbles[i]=-1;
|
||||
for (byte b=0;b<64;b++)
|
||||
rfc1421nibbles[(byte)rfc1421alphabet[b]]=b;
|
||||
rfc1421nibbles[(byte)pad]=0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Base 64 encode as described in RFC 1421.
|
||||
* <p>Does not insert whitespace as described in RFC 1521.
|
||||
* @param s String to encode.
|
||||
* @return String containing the encoded form of the input.
|
||||
*/
|
||||
static public String encode(String s)
|
||||
{
|
||||
try
|
||||
{
|
||||
return encode(s,null);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new IllegalArgumentException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Base 64 encode as described in RFC 1421.
|
||||
* <p>Does not insert whitespace as described in RFC 1521.
|
||||
* @param s String to encode.
|
||||
* @param charEncoding String representing the name of
|
||||
* the character encoding of the provided input String.
|
||||
* @return String containing the encoded form of the input.
|
||||
*/
|
||||
static public String encode(String s,String charEncoding)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
byte[] bytes;
|
||||
if (charEncoding==null)
|
||||
bytes=s.getBytes(StringUtil.__ISO_8859_1);
|
||||
else
|
||||
bytes=s.getBytes(charEncoding);
|
||||
|
||||
return new String(encode(bytes));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Fast Base 64 encode as described in RFC 1421.
|
||||
* <p>Does not insert whitespace as described in RFC 1521.
|
||||
* <p> Avoids creating extra copies of the input/output.
|
||||
* @param b byte array to encode.
|
||||
* @return char array containing the encoded form of the input.
|
||||
*/
|
||||
static public char[] encode(byte[] b)
|
||||
{
|
||||
return encode(b,false);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Fast Base 64 encode as described in RFC 1421 and RFC2045
|
||||
* <p>Does not insert whitespace as described in RFC 1521, unless rfc2045 is passed as true.
|
||||
* <p> Avoids creating extra copies of the input/output.
|
||||
* @param b byte array to encode.
|
||||
* @param rfc2045 If true, break lines at 76 characters with CRLF
|
||||
* @return char array containing the encoded form of the input.
|
||||
*/
|
||||
static public char[] encode(byte[] b, boolean rfc2045)
|
||||
{
|
||||
if (b==null)
|
||||
return null;
|
||||
|
||||
int bLen=b.length;
|
||||
int cLen=((bLen+2)/3)*4;
|
||||
if (rfc2045)
|
||||
cLen+=2+2*cLen/76;
|
||||
char c[]=new char[cLen];
|
||||
int ci=0;
|
||||
int bi=0;
|
||||
byte b0, b1, b2;
|
||||
int stop=(bLen/3)*3;
|
||||
int l=0;
|
||||
while (bi<stop)
|
||||
{
|
||||
b0=b[bi++];
|
||||
b1=b[bi++];
|
||||
b2=b[bi++];
|
||||
c[ci++]=rfc1421alphabet[(b0>>>2)&0x3f];
|
||||
c[ci++]=rfc1421alphabet[(b0<<4)&0x3f|(b1>>>4)&0x0f];
|
||||
c[ci++]=rfc1421alphabet[(b1<<2)&0x3f|(b2>>>6)&0x03];
|
||||
c[ci++]=rfc1421alphabet[b2&077];
|
||||
l+=4;
|
||||
if (rfc2045 && l%76==0)
|
||||
{
|
||||
c[ci++]=13;
|
||||
c[ci++]=10;
|
||||
}
|
||||
}
|
||||
|
||||
if (bLen!=bi)
|
||||
{
|
||||
switch (bLen%3)
|
||||
{
|
||||
case 2:
|
||||
b0=b[bi++];
|
||||
b1=b[bi++];
|
||||
c[ci++]=rfc1421alphabet[(b0>>>2)&0x3f];
|
||||
c[ci++]=rfc1421alphabet[(b0<<4)&0x3f|(b1>>>4)&0x0f];
|
||||
c[ci++]=rfc1421alphabet[(b1<<2)&0x3f];
|
||||
c[ci++]=pad;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
b0=b[bi++];
|
||||
c[ci++]=rfc1421alphabet[(b0>>>2)&0x3f];
|
||||
c[ci++]=rfc1421alphabet[(b0<<4)&0x3f];
|
||||
c[ci++]=pad;
|
||||
c[ci++]=pad;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rfc2045)
|
||||
{
|
||||
c[ci++]=13;
|
||||
c[ci++]=10;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Base 64 decode as described in RFC 2045.
|
||||
* <p>Unlike {@link #decode(char[])}, extra whitespace is ignored.
|
||||
* @param encoded String to decode.
|
||||
* @param charEncoding String representing the character encoding
|
||||
* used to map the decoded bytes into a String.
|
||||
* @return String decoded byte array.
|
||||
* @throws UnsupportedEncodingException if the encoding is not supported
|
||||
* @throws IllegalArgumentException if the input is not a valid
|
||||
* B64 encoding.
|
||||
*/
|
||||
static public String decode(String encoded,String charEncoding)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
byte[] decoded=decode(encoded);
|
||||
if (charEncoding==null)
|
||||
return new String(decoded);
|
||||
return new String(decoded,charEncoding);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Fast Base 64 decode as described in RFC 1421.
|
||||
*
|
||||
* <p>Unlike other decode methods, this does not attempt to
|
||||
* cope with extra whitespace as described in RFC 1521/2045.
|
||||
* <p> Avoids creating extra copies of the input/output.
|
||||
* <p> Note this code has been flattened for performance.
|
||||
* @param b char array to decode.
|
||||
* @return byte array containing the decoded form of the input.
|
||||
* @throws IllegalArgumentException if the input is not a valid
|
||||
* B64 encoding.
|
||||
* @deprecated use {@link org.eclipse.jetty.util.B64Code}
|
||||
*/
|
||||
static public byte[] decode(char[] b)
|
||||
@Deprecated
|
||||
public class B64Code extends org.eclipse.jetty.util.B64Code
|
||||
{
|
||||
if (b==null)
|
||||
return null;
|
||||
|
||||
int bLen=b.length;
|
||||
if (bLen%4!=0)
|
||||
throw new IllegalArgumentException("Input block size is not 4");
|
||||
|
||||
int li=bLen-1;
|
||||
while (li>=0 && b[li]==(byte)pad)
|
||||
li--;
|
||||
|
||||
if (li<0)
|
||||
return new byte[0];
|
||||
|
||||
// Create result array of exact required size.
|
||||
int rLen=((li+1)*3)/4;
|
||||
byte r[]=new byte[rLen];
|
||||
int ri=0;
|
||||
int bi=0;
|
||||
int stop=(rLen/3)*3;
|
||||
byte b0,b1,b2,b3;
|
||||
try
|
||||
public B64Code()
|
||||
{
|
||||
while (ri<stop)
|
||||
{
|
||||
b0=rfc1421nibbles[b[bi++]];
|
||||
b1=rfc1421nibbles[b[bi++]];
|
||||
b2=rfc1421nibbles[b[bi++]];
|
||||
b3=rfc1421nibbles[b[bi++]];
|
||||
if (b0<0 || b1<0 || b2<0 || b3<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
|
||||
r[ri++]=(byte)(b0<<2|b1>>>4);
|
||||
r[ri++]=(byte)(b1<<4|b2>>>2);
|
||||
r[ri++]=(byte)(b2<<6|b3);
|
||||
}
|
||||
|
||||
if (rLen!=ri)
|
||||
{
|
||||
switch (rLen%3)
|
||||
{
|
||||
case 2:
|
||||
b0=rfc1421nibbles[b[bi++]];
|
||||
b1=rfc1421nibbles[b[bi++]];
|
||||
b2=rfc1421nibbles[b[bi++]];
|
||||
if (b0<0 || b1<0 || b2<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
r[ri++]=(byte)(b0<<2|b1>>>4);
|
||||
r[ri++]=(byte)(b1<<4|b2>>>2);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
b0=rfc1421nibbles[b[bi++]];
|
||||
b1=rfc1421nibbles[b[bi++]];
|
||||
if (b0<0 || b1<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
r[ri++]=(byte)(b0<<2|b1>>>4);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
throw new IllegalArgumentException("char "+bi
|
||||
+" was not B64 encoded");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Base 64 decode as described in RFC 2045.
|
||||
* <p>Unlike {@link #decode(char[])}, extra whitespace is ignored.
|
||||
* @param encoded String to decode.
|
||||
* @return byte array containing the decoded form of the input.
|
||||
* @throws IllegalArgumentException if the input is not a valid
|
||||
* B64 encoding.
|
||||
*/
|
||||
static public byte[] decode(String encoded)
|
||||
{
|
||||
if (encoded==null)
|
||||
return null;
|
||||
|
||||
int ci=0;
|
||||
byte nibbles[] = new byte[4];
|
||||
int s=0;
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream(4*encoded.length()/3);
|
||||
|
||||
while (ci<encoded.length())
|
||||
{
|
||||
char c=encoded.charAt(ci++);
|
||||
|
||||
if (c==pad)
|
||||
break;
|
||||
|
||||
if (Character.isWhitespace(c))
|
||||
continue;
|
||||
|
||||
byte nibble=rfc1421nibbles[c];
|
||||
if (nibble<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
|
||||
nibbles[s++]=rfc1421nibbles[c];
|
||||
|
||||
switch(s)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
bout.write(nibbles[0]<<2|nibbles[1]>>>4);
|
||||
break;
|
||||
case 3:
|
||||
bout.write(nibbles[1]<<4|nibbles[2]>>>2);
|
||||
break;
|
||||
case 4:
|
||||
bout.write(nibbles[2]<<6|nibbles[3]);
|
||||
s=0;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return bout.toByteArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,12 +32,12 @@ import javax.security.auth.message.module.ServerAuthModule;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.http.security.Credential;
|
||||
import org.eclipse.jetty.http.security.Password;
|
||||
import org.eclipse.jetty.security.authentication.LoginCallbackImpl;
|
||||
import org.eclipse.jetty.security.jaspi.JaspiMessageInfo;
|
||||
import org.eclipse.jetty.security.jaspi.callback.CredentialValidationCallback;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,9 +25,9 @@ import javax.security.auth.message.MessageInfo;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.http.security.Constraint;
|
||||
import org.eclipse.jetty.http.security.Password;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
|
||||
/**
|
||||
* @deprecated use *ServerAuthentication
|
||||
|
|
|
@ -28,9 +28,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpHeaders;
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.http.security.Constraint;
|
||||
import org.eclipse.jetty.http.security.Credential;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
|
|
|
@ -21,13 +21,13 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpHeaders;
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.http.security.Constraint;
|
||||
import org.eclipse.jetty.security.ServerAuthException;
|
||||
import org.eclipse.jetty.security.UserAuthentication;
|
||||
import org.eclipse.jetty.server.Authentication;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
import org.eclipse.jetty.server.Authentication.User;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,13 +22,13 @@ import javax.servlet.ServletResponse;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.http.security.Constraint;
|
||||
import org.eclipse.jetty.security.ServerAuthException;
|
||||
import org.eclipse.jetty.security.UserAuthentication;
|
||||
import org.eclipse.jetty.server.Authentication;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
import org.eclipse.jetty.server.Authentication.User;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
|
||||
/**
|
||||
* @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
|
||||
|
|
|
@ -22,7 +22,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpHeaders;
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.http.security.Constraint;
|
||||
import org.eclipse.jetty.http.security.Credential;
|
||||
import org.eclipse.jetty.security.Authenticator.AuthConfiguration;
|
||||
|
@ -33,6 +32,7 @@ import org.eclipse.jetty.server.Authentication;
|
|||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
import org.eclipse.jetty.server.Authentication.User;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
|
|
|
@ -27,7 +27,6 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.http.security.Constraint;
|
||||
import org.eclipse.jetty.http.security.Password;
|
||||
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
|
||||
|
@ -41,6 +40,7 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
|
|||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.util.Random;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.server.SessionIdManager;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
|
|
@ -41,7 +41,7 @@ import javax.servlet.ServletResponse;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import org.eclipse.jetty.http.security.B64Code;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.LazyList;
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
|
|
|
@ -0,0 +1,344 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 1999-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Fast B64 Encoder/Decoder as described in RFC 1421.
|
||||
* <p>Does not insert or interpret whitespace as described in RFC
|
||||
* 1521. If you require this you must pre/post process your data.
|
||||
* <p> Note that in a web context the usual case is to not want
|
||||
* linebreaks or other white space in the encoded output.
|
||||
*
|
||||
*/
|
||||
public class B64Code
|
||||
{
|
||||
// ------------------------------------------------------------------
|
||||
static final char pad='=';
|
||||
static final char[] rfc1421alphabet=
|
||||
{
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
|
||||
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
|
||||
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
|
||||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
|
||||
};
|
||||
|
||||
static final byte[] rfc1421nibbles;
|
||||
|
||||
static
|
||||
{
|
||||
rfc1421nibbles=new byte[256];
|
||||
for (int i=0;i<256;i++)
|
||||
rfc1421nibbles[i]=-1;
|
||||
for (byte b=0;b<64;b++)
|
||||
rfc1421nibbles[(byte)rfc1421alphabet[b]]=b;
|
||||
rfc1421nibbles[(byte)pad]=0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Base 64 encode as described in RFC 1421.
|
||||
* <p>Does not insert whitespace as described in RFC 1521.
|
||||
* @param s String to encode.
|
||||
* @return String containing the encoded form of the input.
|
||||
*/
|
||||
static public String encode(String s)
|
||||
{
|
||||
try
|
||||
{
|
||||
return encode(s,null);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new IllegalArgumentException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Base 64 encode as described in RFC 1421.
|
||||
* <p>Does not insert whitespace as described in RFC 1521.
|
||||
* @param s String to encode.
|
||||
* @param charEncoding String representing the name of
|
||||
* the character encoding of the provided input String.
|
||||
* @return String containing the encoded form of the input.
|
||||
*/
|
||||
static public String encode(String s,String charEncoding)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
byte[] bytes;
|
||||
if (charEncoding==null)
|
||||
bytes=s.getBytes(StringUtil.__ISO_8859_1);
|
||||
else
|
||||
bytes=s.getBytes(charEncoding);
|
||||
|
||||
return new String(encode(bytes));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Fast Base 64 encode as described in RFC 1421.
|
||||
* <p>Does not insert whitespace as described in RFC 1521.
|
||||
* <p> Avoids creating extra copies of the input/output.
|
||||
* @param b byte array to encode.
|
||||
* @return char array containing the encoded form of the input.
|
||||
*/
|
||||
static public char[] encode(byte[] b)
|
||||
{
|
||||
return encode(b,false);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Fast Base 64 encode as described in RFC 1421 and RFC2045
|
||||
* <p>Does not insert whitespace as described in RFC 1521, unless rfc2045 is passed as true.
|
||||
* <p> Avoids creating extra copies of the input/output.
|
||||
* @param b byte array to encode.
|
||||
* @param rfc2045 If true, break lines at 76 characters with CRLF
|
||||
* @return char array containing the encoded form of the input.
|
||||
*/
|
||||
static public char[] encode(byte[] b, boolean rfc2045)
|
||||
{
|
||||
if (b==null)
|
||||
return null;
|
||||
|
||||
int bLen=b.length;
|
||||
int cLen=((bLen+2)/3)*4;
|
||||
if (rfc2045)
|
||||
cLen+=2+2*cLen/76;
|
||||
char c[]=new char[cLen];
|
||||
int ci=0;
|
||||
int bi=0;
|
||||
byte b0, b1, b2;
|
||||
int stop=(bLen/3)*3;
|
||||
int l=0;
|
||||
while (bi<stop)
|
||||
{
|
||||
b0=b[bi++];
|
||||
b1=b[bi++];
|
||||
b2=b[bi++];
|
||||
c[ci++]=rfc1421alphabet[(b0>>>2)&0x3f];
|
||||
c[ci++]=rfc1421alphabet[(b0<<4)&0x3f|(b1>>>4)&0x0f];
|
||||
c[ci++]=rfc1421alphabet[(b1<<2)&0x3f|(b2>>>6)&0x03];
|
||||
c[ci++]=rfc1421alphabet[b2&077];
|
||||
l+=4;
|
||||
if (rfc2045 && l%76==0)
|
||||
{
|
||||
c[ci++]=13;
|
||||
c[ci++]=10;
|
||||
}
|
||||
}
|
||||
|
||||
if (bLen!=bi)
|
||||
{
|
||||
switch (bLen%3)
|
||||
{
|
||||
case 2:
|
||||
b0=b[bi++];
|
||||
b1=b[bi++];
|
||||
c[ci++]=rfc1421alphabet[(b0>>>2)&0x3f];
|
||||
c[ci++]=rfc1421alphabet[(b0<<4)&0x3f|(b1>>>4)&0x0f];
|
||||
c[ci++]=rfc1421alphabet[(b1<<2)&0x3f];
|
||||
c[ci++]=pad;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
b0=b[bi++];
|
||||
c[ci++]=rfc1421alphabet[(b0>>>2)&0x3f];
|
||||
c[ci++]=rfc1421alphabet[(b0<<4)&0x3f];
|
||||
c[ci++]=pad;
|
||||
c[ci++]=pad;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rfc2045)
|
||||
{
|
||||
c[ci++]=13;
|
||||
c[ci++]=10;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/**
|
||||
* Base 64 decode as described in RFC 2045.
|
||||
* <p>Unlike {@link #decode(char[])}, extra whitespace is ignored.
|
||||
* @param encoded String to decode.
|
||||
* @param charEncoding String representing the character encoding
|
||||
* used to map the decoded bytes into a String.
|
||||
* @return String decoded byte array.
|
||||
* @throws UnsupportedEncodingException if the encoding is not supported
|
||||
* @throws IllegalArgumentException if the input is not a valid
|
||||
* B64 encoding.
|
||||
*/
|
||||
static public String decode(String encoded,String charEncoding)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
byte[] decoded=decode(encoded);
|
||||
if (charEncoding==null)
|
||||
return new String(decoded);
|
||||
return new String(decoded,charEncoding);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Fast Base 64 decode as described in RFC 1421.
|
||||
*
|
||||
* <p>Unlike other decode methods, this does not attempt to
|
||||
* cope with extra whitespace as described in RFC 1521/2045.
|
||||
* <p> Avoids creating extra copies of the input/output.
|
||||
* <p> Note this code has been flattened for performance.
|
||||
* @param b char array to decode.
|
||||
* @return byte array containing the decoded form of the input.
|
||||
* @throws IllegalArgumentException if the input is not a valid
|
||||
* B64 encoding.
|
||||
*/
|
||||
static public byte[] decode(char[] b)
|
||||
{
|
||||
if (b==null)
|
||||
return null;
|
||||
|
||||
int bLen=b.length;
|
||||
if (bLen%4!=0)
|
||||
throw new IllegalArgumentException("Input block size is not 4");
|
||||
|
||||
int li=bLen-1;
|
||||
while (li>=0 && b[li]==(byte)pad)
|
||||
li--;
|
||||
|
||||
if (li<0)
|
||||
return new byte[0];
|
||||
|
||||
// Create result array of exact required size.
|
||||
int rLen=((li+1)*3)/4;
|
||||
byte r[]=new byte[rLen];
|
||||
int ri=0;
|
||||
int bi=0;
|
||||
int stop=(rLen/3)*3;
|
||||
byte b0,b1,b2,b3;
|
||||
try
|
||||
{
|
||||
while (ri<stop)
|
||||
{
|
||||
b0=rfc1421nibbles[b[bi++]];
|
||||
b1=rfc1421nibbles[b[bi++]];
|
||||
b2=rfc1421nibbles[b[bi++]];
|
||||
b3=rfc1421nibbles[b[bi++]];
|
||||
if (b0<0 || b1<0 || b2<0 || b3<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
|
||||
r[ri++]=(byte)(b0<<2|b1>>>4);
|
||||
r[ri++]=(byte)(b1<<4|b2>>>2);
|
||||
r[ri++]=(byte)(b2<<6|b3);
|
||||
}
|
||||
|
||||
if (rLen!=ri)
|
||||
{
|
||||
switch (rLen%3)
|
||||
{
|
||||
case 2:
|
||||
b0=rfc1421nibbles[b[bi++]];
|
||||
b1=rfc1421nibbles[b[bi++]];
|
||||
b2=rfc1421nibbles[b[bi++]];
|
||||
if (b0<0 || b1<0 || b2<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
r[ri++]=(byte)(b0<<2|b1>>>4);
|
||||
r[ri++]=(byte)(b1<<4|b2>>>2);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
b0=rfc1421nibbles[b[bi++]];
|
||||
b1=rfc1421nibbles[b[bi++]];
|
||||
if (b0<0 || b1<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
r[ri++]=(byte)(b0<<2|b1>>>4);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
throw new IllegalArgumentException("char "+bi
|
||||
+" was not B64 encoded");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Base 64 decode as described in RFC 2045.
|
||||
* <p>Unlike {@link #decode(char[])}, extra whitespace is ignored.
|
||||
* @param encoded String to decode.
|
||||
* @return byte array containing the decoded form of the input.
|
||||
* @throws IllegalArgumentException if the input is not a valid
|
||||
* B64 encoding.
|
||||
*/
|
||||
static public byte[] decode(String encoded)
|
||||
{
|
||||
if (encoded==null)
|
||||
return null;
|
||||
|
||||
int ci=0;
|
||||
byte nibbles[] = new byte[4];
|
||||
int s=0;
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream(4*encoded.length()/3);
|
||||
|
||||
while (ci<encoded.length())
|
||||
{
|
||||
char c=encoded.charAt(ci++);
|
||||
|
||||
if (c==pad)
|
||||
break;
|
||||
|
||||
if (Character.isWhitespace(c))
|
||||
continue;
|
||||
|
||||
byte nibble=rfc1421nibbles[c];
|
||||
if (nibble<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
|
||||
nibbles[s++]=rfc1421nibbles[c];
|
||||
|
||||
switch(s)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
bout.write(nibbles[0]<<2|nibbles[1]>>>4);
|
||||
break;
|
||||
case 3:
|
||||
bout.write(nibbles[1]<<4|nibbles[2]>>>2);
|
||||
break;
|
||||
case 4:
|
||||
bout.write(nibbles[2]<<6|nibbles[3]);
|
||||
s=0;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return bout.toByteArray();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue