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