You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by sm...@apache.org on 2009/10/23 17:42:39 UTC
svn commit: r829094 - in
/incubator/pivot/trunk/core/src/org/apache/pivot/util: HexUtils.java MD5.java
Author: smartini
Date: Fri Oct 23 15:42:39 2009
New Revision: 829094
URL: http://svn.apache.org/viewvc?rev=829094&view=rev
Log:
moved MD5 and HexUtils in core subproject
Added:
incubator/pivot/trunk/core/src/org/apache/pivot/util/HexUtils.java
incubator/pivot/trunk/core/src/org/apache/pivot/util/MD5.java
Added: incubator/pivot/trunk/core/src/org/apache/pivot/util/HexUtils.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/util/HexUtils.java?rev=829094&view=auto
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/util/HexUtils.java (added)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/util/HexUtils.java Fri Oct 23 15:42:39 2009
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Library of utility methods useful in dealing with converting byte arrays
+ * to and from strings of hexadecimal digits.
+ * <br/>
+ * Portions of code here are taken from Apache Tomcat.
+ *
+ * @see org.apache.catalina.util.HexUtils;
+ */
+public final class HexUtils {
+
+ /** Hexadecimal standard chars. */
+ public static final char[] hexadecimal = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ /** Table for HEX to DEC byte translation */
+ public static final int[] DEC = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 00, 01, 02, 03, 04, 05, 06, 07, 8, 9, -1, -1, -1,
+ -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
+
+ /** Constructor for private usage */
+ private HexUtils() {
+ }
+
+ /**
+ * Convert a String of hexadecimal digits into the corresponding byte array
+ * by encoding each two hexadecimal digits as a byte.
+ *
+ * @param digits Hexadecimal digits representation
+ * @exception IllegalArgumentException if an invalid hexadecimal digit is
+ * found, or the input string contains an odd number of hexadecimal digits
+ */
+ public static byte[] convert(String digits) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ for (int i = 0; i < digits.length(); i += 2) {
+ char c1 = digits.charAt(i);
+ if ((i + 1) >= digits.length()) {
+ throw new IllegalArgumentException("bad hex input data");
+ }
+
+ char c2 = digits.charAt(i + 1);
+ byte b = 0;
+ if ((c1 >= '0') && (c1 <= '9')) {
+ b += ((c1 - '0') * 16);
+ }
+ else if ((c1 >= 'a') && (c1 <= 'f')) {
+ b += ((c1 - 'a' + 10) * 16);
+ }
+ else if ((c1 >= 'A') && (c1 <= 'F')) {
+ b += ((c1 - 'A' + 10) * 16);
+ }
+ else {
+ throw new IllegalArgumentException("bad hex input data");
+ }
+
+ if ((c2 >= '0') && (c2 <= '9')) {
+ b += (c2 - '0');
+ }
+ else if ((c2 >= 'a') && (c2 <= 'f')) {
+ b += (c2 - 'a' + 10);
+ }
+ else if ((c2 >= 'A') && (c2 <= 'F')) {
+ b += (c2 - 'A' + 10);
+ }
+ else {
+ throw new IllegalArgumentException("bad hex input data");
+ }
+
+ baos.write(b);
+ }
+
+ return (baos.toByteArray());
+ }
+
+ /**
+ * Convert a byte array into a printable format containing a String of
+ * hexadecimal digit characters (two per byte).
+ *
+ * @param bytes Byte array representation
+ */
+ public static String convert(byte bytes[]) {
+ StringBuffer sb = new StringBuffer(bytes.length * 2);
+ for (int i = 0; i < bytes.length; i++) {
+ sb.append(convertDigit(bytes[i] >> 4));
+ sb.append(convertDigit(bytes[i] & 0x0f));
+ }
+
+ return (sb.toString());
+ }
+
+ /**
+ * Convert 4 hex digits to an int, and return the number of converted bytes.
+ *
+ * @param hex Byte array containing exactly four hexadecimal digits
+ * @exception IllegalArgumentException if an invalid hexadecimal digit is
+ * included
+ */
+ public static int convert2Int(byte[] hex) {
+ // assert valid data
+ int len;
+ if (hex.length < 4) {
+ return 0;
+ }
+ if (DEC[hex[0]] < 0) {
+ throw new IllegalArgumentException("bad hex input data");
+ }
+
+ len = DEC[hex[0]];
+ len = len << 4;
+ if (DEC[hex[1]] < 0) {
+ throw new IllegalArgumentException("bad hex input data");
+ }
+ len += DEC[hex[1]];
+ len = len << 4;
+ if (DEC[hex[2]] < 0) {
+ throw new IllegalArgumentException("bad hex input data");
+ }
+ len += DEC[hex[2]];
+ len = len << 4;
+ if (DEC[hex[3]] < 0) {
+ throw new IllegalArgumentException("bad hex input data");
+ }
+
+ len += DEC[hex[3]];
+ return len;
+ }
+
+ /**
+ * [Private] Convert the specified value (0 .. 15) to the corresponding
+ * hexadecimal digit.
+ *
+ * @param value Value to be converted
+ */
+ private static char convertDigit(int value) {
+ value &= 0x0f;
+
+ if (value >= 10) {
+ return ((char) (value - 10 + 'a'));
+ }
+
+ return ((char) (value + '0'));
+ }
+
+ /**
+ * Given a String and the encoding, returns it as a byte array.
+ *
+ * @param string the string
+ * @param encoding the encoding, or if null a default will be used
+ * @return the string transformed to byte array
+ * @throws UnsupportedEncodingException
+ */
+ public static final byte[] toByteArray(final String string, final String encoding)
+ throws UnsupportedEncodingException {
+ byte[] bytes = null;
+ if (encoding == null) {
+ bytes = string.getBytes();
+ }
+ else {
+ bytes = string.getBytes(encoding);
+ }
+
+ return bytes;
+ }
+
+}
Added: incubator/pivot/trunk/core/src/org/apache/pivot/util/MD5.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/util/MD5.java?rev=829094&view=auto
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/util/MD5.java (added)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/util/MD5.java Fri Oct 23 15:42:39 2009
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.util;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Encode / Decode an MD5 digest into / from 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.
+ * <br/>
+ * Portions of code here are taken from Apache Tomcat.
+ *
+ * TODO:
+ * - verify if it's safe also without the synchronization statement ...
+ *
+ * @see org.apache.catalina.util.MD5Encoder
+ */
+public final class MD5 {
+ public static final int MD5_DIGEST_LENTGH_IN_BYTES = 16;
+ public static final String MD5_ALGORITHM_NAME = "MD5";
+
+ /** The MD5 message digest generator. */
+ private static MessageDigest md5 = null;
+
+ /** Constructor for private usage */
+ private MD5() {
+ }
+
+ /**
+ * Retrieves a byte sequence representing the MD5 digest of the specified
+ * byte sequence. Note that any Exception is handled inside.
+ *
+ * @param data the data to digest.
+ * @return the MD5 digest as an array of 16 bytes.
+ */
+ public static final byte[] digest(byte[] data) {
+ if (data == null) {
+ throw new IllegalArgumentException("null data");
+ }
+
+ byte[] dataDigested = null;
+
+ // synchronized (MD5.class) {
+ if (md5 == null) {
+ try {
+ md5 = MessageDigest.getInstance(MD5_ALGORITHM_NAME);
+ } catch (NoSuchAlgorithmException e) {
+ md5 = null;
+ }
+ }
+
+ if (md5 != null) {
+ dataDigested = md5.digest(data);
+ }
+
+ // }
+
+ return dataDigested;
+ }
+
+ /**
+ * Transform the given string in a byte array, using the given encoding.
+ * Note that any Exception is handled inside.
+ *
+ * @param string the string
+ * @param encoding the encoding, or if null a default will be used
+ * @return the string transformed to byte array
+ */
+ public static final byte[] digest(final String string, final String encoding) {
+ byte[] data = null;
+ try {
+ data = HexUtils.toByteArray(string, encoding);
+ } catch (UnsupportedEncodingException e) {
+ }
+
+ byte[] dataDigested = digest(data);
+ return dataDigested;
+ }
+
+ public static boolean isEqual(byte[] digesta, byte[] digestb) {
+ // Two arrays are equal if they have the same length and each element
+ // is equal to the corresponding element in the other array;
+ // otherwise, they aren't.
+
+ if (digesta == null || digestb == null) {
+ return false;
+ }
+ else if (digesta.length == MD5_DIGEST_LENTGH_IN_BYTES
+ && digestb.length == MD5_DIGEST_LENTGH_IN_BYTES) {
+ for (int i = 0; i < MD5_DIGEST_LENTGH_IN_BYTES; i++) {
+ if (digesta[i] != digestb[i])
+ return false;
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * Encodes the 128 bit (16 bytes) MD5 into a 32 character String.
+ *
+ * @param binaryData The Array containing the digest
+ * @return Encoded MD5, or null if encoding failed
+ */
+ public static final String encode(byte[] binaryData) {
+ if (binaryData.length != MD5_DIGEST_LENTGH_IN_BYTES) {
+ throw new IllegalArgumentException("binaryData must be an array of 16 bytes");
+ }
+
+ char[] buffer = new char[MD5_DIGEST_LENTGH_IN_BYTES * 2];
+
+ for (int i = 0; i < MD5_DIGEST_LENTGH_IN_BYTES; i++) {
+ int low = binaryData[i] & 0x0f;
+ int high = (binaryData[i] & 0xf0) >> 4;
+
+ buffer[i * 2] = HexUtils.hexadecimal[high];
+ buffer[i * 2 + 1] = HexUtils.hexadecimal[low];
+ }
+
+ return new String(buffer);
+ }
+
+ /**
+ * Transform the given string in a digested version, using the given encoding.
+ *
+ * @param string the string
+ * @param encoding the encoding, or if null a default will be used
+ * @return the string digested, and transformed as s String
+ */
+ public static final String digestAsString(final String string, final String encoding) {
+ byte[] digestBytes = MD5.digest(string, encoding);
+ String dataDigested = MD5.encode(digestBytes);
+
+ return dataDigested;
+ }
+
+}