Source for java.util.zip.Adler32

   1: /* Adler32.java - Computes Adler32 data checksum of a data stream
   2:    Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package java.util.zip;
  39: 
  40: /*
  41:  * Written using on-line Java Platform 1.2 API Specification, as well
  42:  * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
  43:  * The actual Adler32 algorithm is taken from RFC 1950.
  44:  * Status:  Believed complete and correct.
  45:  */
  46: 
  47: /**
  48:  * Computes Adler32 checksum for a stream of data. An Adler32
  49:  * checksum is not as reliable as a CRC32 checksum, but a lot faster to
  50:  * compute.
  51:  *<p>
  52:  * The specification for Adler32 may be found in RFC 1950.
  53:  * (ZLIB Compressed Data Format Specification version 3.3)
  54:  *<p>
  55:  *<p>
  56:  * From that document:
  57:  *<p>
  58:  *      "ADLER32 (Adler-32 checksum)
  59:  *       This contains a checksum value of the uncompressed data
  60:  *       (excluding any dictionary data) computed according to Adler-32
  61:  *       algorithm. This algorithm is a 32-bit extension and improvement
  62:  *       of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
  63:  *       standard.
  64:  *<p>
  65:  *       Adler-32 is composed of two sums accumulated per byte: s1 is
  66:  *       the sum of all bytes, s2 is the sum of all s1 values. Both sums
  67:  *       are done modulo 65521. s1 is initialized to 1, s2 to zero.  The
  68:  *       Adler-32 checksum is stored as s2*65536 + s1 in most-
  69:  *       significant-byte first (network) order."
  70:  *<p>
  71:  * "8.2. The Adler-32 algorithm
  72:  *<p>
  73:  *    The Adler-32 algorithm is much faster than the CRC32 algorithm yet
  74:  *    still provides an extremely low probability of undetected errors.
  75:  *<p>
  76:  *    The modulo on unsigned long accumulators can be delayed for 5552
  77:  *    bytes, so the modulo operation time is negligible.  If the bytes
  78:  *    are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
  79:  *    and order sensitive, unlike the first sum, which is just a
  80:  *    checksum.  That 65521 is prime is important to avoid a possible
  81:  *    large class of two-byte errors that leave the check unchanged.
  82:  *    (The Fletcher checksum uses 255, which is not prime and which also
  83:  *    makes the Fletcher check insensitive to single byte changes 0 <->
  84:  *    255.)
  85:  *<p>
  86:  *    The sum s1 is initialized to 1 instead of zero to make the length
  87:  *    of the sequence part of s2, so that the length does not have to be
  88:  *   checked separately. (Any sequence of zeroes has a Fletcher
  89:  *    checksum of zero.)"
  90:  *
  91:  * @author John Leuner, Per Bothner
  92:  * @since JDK 1.1
  93:  *
  94:  * @see InflaterInputStream
  95:  * @see DeflaterOutputStream
  96:  */
  97: public class Adler32 implements Checksum
  98: {
  99: 
 100:   /** largest prime smaller than 65536 */
 101:   private static final int BASE = 65521;
 102: 
 103:   private int checksum; //we do all in int.
 104: 
 105:   //Note that java doesn't have unsigned integers,
 106:   //so we have to be careful with what arithmetic
 107:   //we do. We return the checksum as a long to
 108:   //avoid sign confusion.
 109: 
 110:   /**
 111:    * Creates a new instance of the <code>Adler32</code> class.
 112:    * The checksum starts off with a value of 1.
 113:    */
 114:   public Adler32 ()
 115:   {
 116:     reset();
 117:   }
 118: 
 119:   /**
 120:    * Resets the Adler32 checksum to the initial value.
 121:    */
 122:   public void reset ()
 123:   {
 124:     checksum = 1; //Initialize to 1
 125:   }
 126: 
 127:   /**
 128:    * Updates the checksum with the byte b.
 129:    *
 130:    * @param bval the data value to add. The high byte of the int is ignored.
 131:    */
 132:   public void update (int bval)
 133:   {
 134:     //We could make a length 1 byte array and call update again, but I
 135:     //would rather not have that overhead
 136:     int s1 = checksum & 0xffff;
 137:     int s2 = checksum >>> 16;
 138: 
 139:     s1 = (s1 + (bval & 0xFF)) % BASE;
 140:     s2 = (s1 + s2) % BASE;
 141: 
 142:     checksum = (s2 << 16) + s1;
 143:   }
 144: 
 145:   /**
 146:    * Updates the checksum with the bytes taken from the array.
 147:    *
 148:    * @param buffer an array of bytes
 149:    */
 150:   public void update (byte[] buffer)
 151:   {
 152:     update(buffer, 0, buffer.length);
 153:   }
 154: 
 155:   /**
 156:    * Updates the checksum with the bytes taken from the array.
 157:    *
 158:    * @param buf an array of bytes
 159:    * @param off the start of the data used for this update
 160:    * @param len the number of bytes to use for this update
 161:    */
 162:   public void update (byte[] buf, int off, int len)
 163:   {
 164:     //(By Per Bothner)
 165:     int s1 = checksum & 0xffff;
 166:     int s2 = checksum >>> 16;
 167: 
 168:     while (len > 0)
 169:       {
 170:         // We can defer the modulo operation:
 171:         // s1 maximally grows from 65521 to 65521 + 255 * 3800
 172:         // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
 173:         int n = 3800;
 174:         if (n > len)
 175:           n = len;
 176:         len -= n;
 177:         while (--n >= 0)
 178:           {
 179:             s1 = s1 + (buf[off++] & 0xFF);
 180:             s2 = s2 + s1;
 181:           }
 182:         s1 %= BASE;
 183:         s2 %= BASE;
 184:       }
 185: 
 186:     /*Old implementation, borrowed from somewhere:
 187:     int n;
 188: 
 189:     while (len-- > 0) {
 190: 
 191:       s1 = (s1 + (bs[offset++] & 0xff)) % BASE;
 192:       s2 = (s2 + s1) % BASE;
 193:     }*/
 194: 
 195:     checksum = (s2 << 16) | s1;
 196:   }
 197: 
 198:   /**
 199:    * Returns the Adler32 data checksum computed so far.
 200:    */
 201:   public long getValue()
 202:   {
 203:     return (long) checksum & 0xffffffffL;
 204:   }
 205: }