You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by re...@locus.apache.org on 2000/06/25 09:12:23 UTC
cvs commit: jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/util Base64.java MD5Encoder.java
remm 00/06/25 00:12:23
Modified: src/clients/webdav/src/org/apache/webdav/cmd Main.java
src/clients/webdav/src/org/apache/webdav/lib
WebdavClient.java
Added: src/clients/webdav/src/org/apache/webdav/lib
Authenticator.java
src/clients/webdav/src/org/apache/webdav/lib/util
Base64.java MD5Encoder.java
Log:
- Adds authentication support (Basic only for now). If the server
issues a challenge, the client library will automatically answer
using the credentials provided.
- Adds utilities (Base64 encoder / decoder, MD5 to ascii encoder)
which are or will be used by the Authenticator.
- Main sample class uses authentication.
Revision Changes Path
1.2 +16 -4 jakarta-slide/src/clients/webdav/src/org/apache/webdav/cmd/Main.java
Index: Main.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/cmd/Main.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Main.java 2000/06/19 07:31:06 1.1
+++ Main.java 2000/06/25 07:12:21 1.2
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/cmd/Main.java,v 1.1 2000/06/19 07:31:06 remm Exp $
- * $Revision: 1.1 $
- * $Date: 2000/06/19 07:31:06 $
+ * $Header: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/cmd/Main.java,v 1.2 2000/06/25 07:12:21 remm Exp $
+ * $Revision: 1.2 $
+ * $Date: 2000/06/25 07:12:21 $
*
* ====================================================================
*
@@ -104,14 +104,26 @@
client.startSession(host, port);
+ // Set the credentials to use
+ Credentials credentials = new Credentials("root", "root");
+ client.setCredentials(credentials);
+
WebdavMethod method = new GetMethod();
- method.setPath("/index.html");
+ method.setPath("/test");
client.executeMethod(method);
System.out.println("Response :");
System.out.println("Status code : " + method.getStatusCode());
System.out.println("Status text : " + method.getStatusText());
+ WebdavMethod method2 = new GetMethod();
+ method.setPath("/");
+ client.executeMethod(method2);
+
+ System.out.println("Response :");
+ System.out.println("Status code : " + method2.getStatusCode());
+ System.out.println("Status text : " + method2.getStatusText());
+
} catch (Throwable t) {
t.printStackTrace();
}
1.3 +36 -53 jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/WebdavClient.java
Index: WebdavClient.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/WebdavClient.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- WebdavClient.java 2000/06/20 00:22:36 1.2
+++ WebdavClient.java 2000/06/25 07:12:22 1.3
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/WebdavClient.java,v 1.2 2000/06/20 00:22:36 remm Exp $
- * $Revision: 1.2 $
- * $Date: 2000/06/20 00:22:36 $
+ * $Header: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/WebdavClient.java,v 1.3 2000/06/25 07:12:22 remm Exp $
+ * $Revision: 1.3 $
+ * $Date: 2000/06/25 07:12:22 $
*
* ====================================================================
*
@@ -161,46 +161,39 @@
public void executeMethod(WebdavMethod method)
throws IOException, WebdavException {
- sendRequest(method);
+ int authRetries = 0;
- // Parsing response
+ Hashtable responseHeaders = null;
- // Parse status line
- parseStatusLine(readLine(input), method);
-
- // Parse headers
- Hashtable responseHeaders = parseHeaders(input);
-
- // Retrieve the authenticate challenge, if any (needed in case of a
- // digest challenge, for which the header is not constant)
- Header authenticateChallenge =
- (Header) responseHeaders.get("www-authenticate");
- if (authenticateChallenge != null) {
- state.setAuthenticateToken(authenticateChallenge.getValue());
+ while ( (authRetries == 0) ||
+ ((method.getStatusCode() == WebdavStatus.SC_UNAUTHORIZED)
+ && (authRetries < 3)) ) {
+
+ sendRequest(method);
+
+ // Parsing response
+
+ // Parse status line
+ parseStatusLine(readLine(input), method);
+
+ // Parse headers
+ responseHeaders = parseHeaders(input);
+
+ // Retrieve the authenticate challenge, if any
+ // (needed in case of a digest challenge, for which the header is
+ // not constant)
+ Header authenticateChallenge =
+ (Header) responseHeaders.get("www-authenticate");
+ if (authenticateChallenge != null) {
+ state.setAuthenticateToken(authenticateChallenge.getValue());
+ }
+
+ authRetries++;
+
}
- if (method.getStatusCode() == WebdavStatus.SC_UNAUTHORIZED) {
- if (state.getAuthenticateToken() != null) {
-
- // Resumit the request
- System.out.println("Resubmit request using challenge : "
- + state.getAuthenticateToken());
-
- // String authenticateResponse =
- // generateAuthenticateResponse(state.getAuthenticateToken());
- // sendRequest(method, authenticateResponse);
- // parseStatusLine(readLine(input), method);
- // Parse headers
- // responseHeaders = parseHeaders(input);
- // authenticateChallenge =
- // (Header) responseHeaders.get("www-authenticate");
- // if (authenticateChallenge != null) {
- // state.setAuthenticateToken(authenticateChallenge.getValue());
- // }
-
- } else {
- throw new WebdavException("Unable to authenticate");
- }
+ if (authRetries == 3) {
+ throw new WebdavException("Unable to authenticate");
}
method.processResponseHeaders(responseHeaders.elements());
@@ -275,18 +268,6 @@
*/
private void sendRequest(WebdavMethod method)
throws IOException, WebdavException {
- sendRequest(method, null);
- }
-
-
- /**
- * Send a WebDAV request.
- *
- * @param method WebDAV method to execute
- * @param authenticateHeader WWW-Authenticate header value
- */
- private void sendRequest(WebdavMethod method, String authenticateHeader)
- throws IOException, WebdavException {
String requestLine = method.generateRequestLine();
method.generateHeaders(state);
@@ -304,8 +285,10 @@
if (state.getAuthenticateToken() != null) {
- // TODO : Return an appropriate response to the challenge
- System.out.println("Answer to the challenge");
+ String challengeResponse = Authenticator.challengeResponse
+ (state.getAuthenticateToken(), credentials);
+ output.write(("Authorization: "
+ + challengeResponse + "\r\n").getBytes());
}
1.1 jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/Authenticator.java
Index: Authenticator.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/Authenticator.java,v 1.1 2000/06/25 07:12:22 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/06/25 07:12:22 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.webdav.lib;
import java.io.IOException;
import java.util.*;
import org.apache.webdav.lib.util.*;
/**
* Authenticate helper.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class Authenticator {
// ----------------------------------------------------- Instance Variables
/**
* Base 64 encoder.
*/
protected static Base64 base64 = new Base64();
// ------------------------------------------------------------- Properties
/**
* Generate a response to the given challenge.
*
* @param challenge Challenge
* @param credentials Credentials to use to answser the challenge
* @return String response to the challenge
*/
public static String challengeResponse(String challenge,
Credentials credentials)
throws WebdavException {
if (challenge.startsWith("Basic")) {
return basic(credentials);
} else if (challenge.startsWith("Digest")) {
// FIXME !
}
return null;
}
/**
* Generate a basic response.
*
* @param credentials Credentials to use to answser the challenge
*/
public static String basic(Credentials credentials) {
String authString = credentials.getUserName() + ":"
+ credentials.getPassword();
return "Basic " + new String(base64.encode(authString.getBytes()));
}
}
1.1 jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/util/Base64.java
Index: Base64.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/util/Base64.java,v 1.1 2000/06/25 07:12:23 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/06/25 07:12:23 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.webdav.lib.util;
/**
* This class provides encode/decode for RFC 2045 Base64 as
* defined by RFC 2045, N. Freed and N. Borenstein.
* RFC 2045: Multipurpose Internet Mail Extensions (MIME)
* Part One: Format of Internet Message Bodies. Reference
* 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt
* This class is used by XML Schema binary format validation
*
* @author Jeffrey Rodriguez
* @version $Revision: 1.1 $ $Date: 2000/06/25 07:12:23 $
*/
public final class Base64 {
static private final int BASELENGTH = 255;
static private final int LOOKUPLENGTH = 63;
static private final int TWENTYFOURBITGROUP = 24;
static private final int EIGHTBIT = 8;
static private final int SIXTEENBIT = 16;
static private final int SIXBIT = 6;
static private final int FOURBYTE = 4;
static private final byte PAD = ( byte ) '=';
static private byte [] base64Alphabet = new byte[BASELENGTH];
static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
static {
for (int i = 0; i<BASELENGTH; i++ ) {
base64Alphabet[i] = -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 );
}
static boolean isBase64( byte octect ) {
//shall we ignore white space? JEFF??
return(octect == PAD || base64Alphabet[octect] != -1 );
}
static boolean isArrayByteBase64( byte[] arrayOctect ) {
int length = arrayOctect.length;
if ( length == 0 )
return false;
for ( int i=0; i < length; i++ ) {
if ( Base64.isBase64( arrayOctect[i] ) == false)
return false;
}
return true;
}
/**
* Encodes hex octects into Base64
*
* @param binaryData Array containing binaryData
* @return Encoded Base64 array
*/
public byte[] encode( byte[] binaryData ) {
int lengthDataBits = binaryData.length*EIGHTBIT;
int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP;
int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP;
byte encodedData[] = null;
if ( fewerThan24bits != 0 ) //data not divisible by 24 bit
encodedData = new byte[ (numberTriplets + 1 )*4 ];
else // 16 or 8 bit
encodedData = new byte[ numberTriplets*4 ];
byte k=0, l=0, b1=0,b2=0,b3=0;
int encodedIndex = 0;
int dataIndex = 0;
int i = 0;
for ( i = 0; i<numberTriplets; i++ ) {
dataIndex = i*3;
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1];
b3 = binaryData[dataIndex + 2];
l = (byte)(b2 & 0x0f);
k = (byte)(b1 & 0x03);
encodedIndex = i*4;
encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
encodedData[encodedIndex+1] = lookUpBase64Alphabet[(b2 >>4 ) |
( k<<4 )];
encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2 ) |
( b3>>6)];
encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ];
}
// form integral number of 6-bit groups
dataIndex = i*3;
encodedIndex = i*4;
if (fewerThan24bits == EIGHTBIT ) {
b1 = binaryData[dataIndex];
k = (byte) ( b1 &0x03 );
encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ];
encodedData[encodedIndex + 2] = PAD;
encodedData[encodedIndex + 3] = PAD;
} else if ( fewerThan24bits == SIXTEENBIT ) {
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex +1 ];
l = ( byte ) ( b2 &0x0f );
k = ( byte ) ( b1 &0x03 );
encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ (b2 >>4 )
| ( k<<4 )];
encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ];
encodedData[encodedIndex + 3] = PAD;
}
return encodedData;
}
/**
* Decodes Base64 data into octects
*
* @param binaryData Byte array containing Base64 data
* @return Array containind decoded data.
*/
public byte[] decode( byte[] base64Data ) {
int numberQuadruple = base64Data.length/FOURBYTE;
byte decodedData[] = null;
byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;
// Throw away anything not in base64Data
// Adjust size
int encodedIndex = 0;
int dataIndex = 0;
decodedData = new byte[ numberQuadruple*3 + 1 ];
for (int i = 0; i<numberQuadruple; i++ ) {
dataIndex = i*4;
marker0 = base64Data[dataIndex +2];
marker1 = base64Data[dataIndex +3];
b1 = base64Alphabet[base64Data[dataIndex]];
b2 = base64Alphabet[base64Data[dataIndex +1]];
if ( marker0 != PAD && marker1 != PAD ) { //No PAD e.g 3cQl
b3 = base64Alphabet[ marker0 ];
b4 = base64Alphabet[ marker1 ];
decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |(
(b3>>2) & 0xf) );
decodedData[encodedIndex+2] = (byte)( b3<<6 | b4 );
} else if ( marker0 == PAD ) { //Two PAD e.g. 3c[Pad][Pad]
decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
decodedData[encodedIndex+1] = (byte)((b2 & 0xf)<<4 );
decodedData[encodedIndex+2] = (byte) 0;
} else if ( marker1 == PAD ) { //One PAD e.g. 3cQ[Pad]
b3 = base64Alphabet[ marker0 ];
decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 );
decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |(
(b3>>2) & 0xf) );
decodedData[encodedIndex+2] = (byte)( b3<<6);
}
encodedIndex += 3;
}
return decodedData;
}
}
1.1 jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/util/MD5Encoder.java
Index: MD5Encoder.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/clients/webdav/src/org/apache/webdav/lib/util/MD5Encoder.java,v 1.1 2000/06/25 07:12:23 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/06/25 07:12:23 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.webdav.lib.util;
/**
* Encode an MD5 digest into a String.
* <p>
* The 128 bit MD5 hash is converted into a 32 character long String.
* Each character of the String is the hexadecimal representation of 4 bits
* of the digest.
*
* @author Remy Maucherat
* @version $Revision: 1.1 $ $Date: 2000/06/25 07:12:23 $
*/
public final class MD5Encoder {
// ----------------------------------------------------- Instance Variables
private static final char[] hexadecimal =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
// --------------------------------------------------------- Public Methods
/**
* Encodes the 128 bit (16 bytes) MD5 into a 32 character String.
*
* @param binaryData Array containing the digest
* @return Encoded MD5, or null if encoding failed
*/
public String encode( byte[] binaryData ) {
if (binaryData.length != 16)
return null;
char[] buffer = new char[32];
for (int i=0; i<16; i++) {
int low = (int) (binaryData[i] & 0x0f);
int high = (int) ((binaryData[i] & 0xf0) >> 4);
buffer[i*2] = hexadecimal[high];
buffer[i*2 + 1] = hexadecimal[low];
}
return new String(buffer);
}
}