You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ba...@apache.org on 2008/03/08 08:51:44 UTC

svn commit: r634904 - in /commons/proper/codec/trunk/src: java/org/apache/commons/codec/binary/Base64.java test/org/apache/commons/codec/binary/Base64Test.java

Author: bayard
Date: Fri Mar  7 23:51:41 2008
New Revision: 634904

URL: http://svn.apache.org/viewvc?rev=634904&view=rev
Log:
Adding Chris Black's patch from CODEC-40 adding BigInteger support to Base64. Still needs edge case testing

Modified:
    commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java
    commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java

Modified: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java?rev=634904&r1=634903&r2=634904&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java (original)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java Fri Mar  7 23:51:41 2008
@@ -22,6 +22,8 @@
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.EncoderException;
 
+import java.math.BigInteger;
+
 /**
  * Provides Base64 encoding and decoding as defined by RFC 2045.
  * 
@@ -532,4 +534,67 @@
         return encodeBase64(pArray, false);
     }
 
+    // Implementation of integer encoding used for crypto
+    /**
+     * Decode a byte64-encoded integer according to crypto
+     * standards such as W3C's XML-Signature
+     * 
+     * @param pArray a byte array containing base64 character data
+     * @return A BigInteger
+     */
+    public static BigInteger decodeInteger(byte[] pArray) {
+        return new BigInteger(1, decodeBase64(pArray));
+    }
+
+    /**
+     * Encode to a byte64-encoded integer according to crypto
+     * standards such as W3C's XML-Signature
+     * 
+     * @param bigInt a BigInteger
+     * @return A byte array containing base64 character data
+     * @throws NullPointerException if null is passed in
+     */
+    public static byte[] encodeInteger(BigInteger bigInt) {
+        if(bigInt == null)  {
+            throw new NullPointerException("encodeInteger called with null parameter");
+        }
+
+        return encodeBase64(toIntegerBytes(bigInt), false);
+    }
+
+    /**
+     * Returns a byte-array representation of a <code>BigInteger</code>
+     * without sign bit.
+     *
+     * @param bigInt <code>BigInteger</code> to be converted
+     * @return a byte array representation of the BigInteger parameter
+     */
+     static byte[] toIntegerBytes(BigInteger bigInt) {
+        int bitlen = bigInt.bitLength();
+        // round bitlen
+        bitlen = ((bitlen + 7) >> 3) << 3;
+        byte[] bigBytes = bigInt.toByteArray();
+
+        if(((bigInt.bitLength() % 8) != 0)
+            && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) {
+            return bigBytes;
+        }
+
+        // set up params for copying everything but sign bit
+        int startSrc = 0;
+        int len = bigBytes.length;
+
+        // if bigInt is exactly byte-aligned, just skip signbit in copy
+        if((bigInt.bitLength() % 8) == 0) {
+            startSrc = 1;
+            len--;
+        }
+
+        int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec
+        byte[] resizedBytes = new byte[bitlen / 8];
+
+        System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len);
+
+        return resizedBytes;
+    }
 }

Modified: commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java?rev=634904&r1=634903&r2=634904&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java (original)
+++ commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java Fri Mar  7 23:51:41 2008
@@ -20,7 +20,7 @@
 
 import java.util.Arrays;
 import java.util.Random;
-
+import java.math.BigInteger;
 import junit.framework.TestCase;
 
 /**
@@ -636,6 +636,55 @@
                 destFromWS.equals( orig ) );
         assertTrue( "Dest string doesn't eausl original", 
                 destFromNoWS.equals( orig ) );
+    }
+
+    public void testCodeInteger1() {
+        String encodedInt1 = "li7dzDacuo67Jg7mtqEm2TRuOMU=";
+        BigInteger bigInt1 = new BigInteger("85739377120809420210425962799" +
+            "0318636601332086981");
+
+    	assertEquals(encodedInt1, new String(Base64.encodeInteger(bigInt1)));
+        assertEquals(bigInt1, Base64.decodeInteger(encodedInt1.getBytes()));
+    }
+
+    public void testCodeInteger2() {
+        String encodedInt2 = "9B5ypLY9pMOmtxCeTDHgwdNFeGs=";
+        BigInteger bigInt2 = new BigInteger("13936727572861167254666467268" +
+            "91466679477132949611");
+
+        assertEquals(encodedInt2, new String(Base64.encodeInteger(bigInt2)));
+        assertEquals(bigInt2, Base64.decodeInteger(encodedInt2.getBytes()));
+    }
+
+    public void testCodeInteger3() {
+        String encodedInt3 = "FKIhdgaG5LGKiEtF1vHy4f3y700zaD6QwDS3IrNVGzNp2" +
+            "rY+1LFWTK6D44AyiC1n8uWz1itkYMZF0/aKDK0Yjg==";
+        BigInteger bigInt3 = new BigInteger("10806548154093873461951748545" +
+            "1196989136416448805819079363524309897749044958112417136240557" +
+            "4495062430572478766856090958495998158114332651671116876320938126");
+
+        assertEquals(encodedInt3, new String(Base64.encodeInteger(bigInt3)));
+        assertEquals(bigInt3, Base64.decodeInteger(encodedInt3.getBytes()));
+    }
+
+    public void testCodeInteger4() {
+        String encodedInt4 = "ctA8YGxrtngg/zKVvqEOefnwmViFztcnPBYPlJsvh6yKI" +
+            "4iDm68fnp4Mi3RrJ6bZAygFrUIQLxLjV+OJtgJAEto0xAs+Mehuq1DkSFEpP3o" +
+            "DzCTOsrOiS1DwQe4oIb7zVk/9l7aPtJMHW0LVlMdwZNFNNJoqMcT2ZfCPrfvYv" +
+            "Q0=";
+        BigInteger bigInt4 = new BigInteger("80624726256040348115552042320" +
+            "6968135001872753709424419772586693950232350200555646471175944" +
+             "519297087885987040810778908507262272892702303774422853675597" +
+             "748008534040890923814202286633163248086055216976551456088015" +
+             "338880713818192088877057717530169381044092839402438015097654" +
+             "53542091716518238707344493641683483917");
+
+        assertEquals(encodedInt4, new String(Base64.encodeInteger(bigInt4)));
+        assertEquals(bigInt4, Base64.decodeInteger(encodedInt4.getBytes()));
+    }
+
+    public void testCodeIntegerEdgeCases() {
+        // TODO
     }
 
     // -------------------------------------------------------- Private Methods