1   /* $RCSfile: ISO9796Part1BitString.java,v $
2    * $Revision: 1.4 $
3    * $Date: 2002/05/31 12:59:46 $
4    * $Author: uwe_guenther $
5    * $State: Exp $
6    *
7    * Created on December 19, 2001 9:16 AM
8    *
9    * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
10   *
11   * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12   * ServiceProvider is a library, written in JavaTM, that should be 
13   * used in HBCI banking applications (clients and may be servers),
14   * to do cryptographic operations.
15   *
16   * The jhbci library is free software; you can redistribute it and/or
17   * modify it under the terms of the GNU Lesser General Public
18   * License as published by the Free Software Foundation; either
19   * version 2.1 of the License, or (at your option) any later version.
20   *
21   * The jhbci library is distributed in the hope that it will be useful,
22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   * Lesser General Public License for more details.
25   *
26   * You should have received a copy of the GNU Lesser General Public
27   * License along with this library; if not, write to the Free Software
28   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29   *
30   */
31  
32  package de.cscc.crypto.provider;
33  
34  import java.util.Arrays;
35  
36  import de.cscc.crypto.util.ByteUtil;
37  
38  /** 
39   * ISO9796Part1BitString Class. This is an immutable class that represents
40   * an right aligned ISO9796-1 bit string. The 'bitLength ' least significant
41   * bits  are information bearing. The (bitString.-length - bitLength) most
42   * significant bits are padded with zero bits. This will be done while 
43   * construction of a object of this class.
44   *
45   * @author  <a href=mailto:uwe@cscc.de>Uwe G&uuml;nther</a>
46   *
47   * @version $Revision: 1.4 $
48   */
49  final class ISO9796Part1BitString {
50  
51      /** Holds the bitString. */
52      private byte[] bitString;
53      
54      /** Holds the bit length of the bitString. */
55      private int bitLength;
56      
57      /** 
58       * Creates new ISO9796Part1BitString
59       * 
60       * @param bitString the byte array with the bitString, that contains at 
61       * least one byte. The bits are counted from right to left starting at one.
62       * @param bitLength the number of of bits that are valid in the bitString
63       * array, counted from the right side. This means if you have byte[8] array
64       * and a bitLength of 59 you have always 8 bits in byte 7 until byte 1 and
65       * the 3 least significant bits in byte 0. If the bitString is to small,
66       * we will bad it with 0x00 bytes on the left side, and is it to big we will
67       * it on the left side and may mask it out on the left side.
68       * @throws NullPointerException if bitString is null.
69       * @throws IllegalArgumentException if bitLength < 1.
70       */
71      ISO9796Part1BitString(byte[] bitString, int bitLength) {
72          if (bitString == null) {
73              throw new NullPointerException("Prameter bitString is null.");
74          }
75          if (bitLength < 1) {
76              throw new IllegalArgumentException("Parameter bitLength have to " +
77              "be at least one.");
78          }
79          
80          //targetLength is only a helper for the following three cases.
81          int targetLength = 0;
82          if (bitLength % 8 == 0) {
83              targetLength = bitLength / 8;
84          } else  /*(bitLength % 8 != 0)*/ {
85              targetLength = bitLength / 8 + 1;
86          }        
87          
88          
89          /*
90           * There follows three cases:
91           *
92           * 1. The parameter bitString[] has lesser bytes than we can put into 
93           *    the member this.bitString[] in dependence on the parameter 
94           *    bitLength. In this case we pad the new this.bitString[] with 0x00 
95           *    bytes to the left. All bits that we got from the parameter 
96           *    bitString[] will be used!
97           *   
98           *    Example:
99           *         bitString             [0][1][2][3]      bitString.length: 4   
100          *    this.bitString [0][1][2][3][4][5][6][7] this.bitString.length: 8
101          *                    ^__^__^__^
102          *                    Filled with 0x00
103          */
104         if (bitString.length < targetLength) {
105             //fill
106             this.bitString = new byte[targetLength];
107             for (int i = 0; i < bitString.length; i++) {
108                 //Copy defensive the bitString to this immutable object.
109                 this.bitString[targetLength-bitString.length+i] = bitString[i];
110             }
111         }
112         /*
113          * 2. The parameter bitString[] has more bytes than we can put into the
114          *    member this.bitString[] in dependence on the parameter bitLength.
115          *    In this case, we cat the unnecessary leftmost bytes, so that the 
116          *    copy process start on the leftmost byte until the this.bitString[]
117          *    is full. Also we have to mask out unused bits in this.bitString[0]
118          *    in dependence of the parameter bitLength.
119          *
120          *    Example:
121          *         bitString [0][1][2][3][4][5][6][7]       bitString.length: 8   
122          *    this.bitString                [0][1][2]  this.bitString.length: 3
123          *                    ^__^__^__^__^
124          *                   Cuting this bytes
125          *
126          *    Further if bitLength would be 20, we have to mask out thje four
127          *    leftmost bits of this.bitString[0] or bitString[5] in this case.
128          */
129         else if(bitString.length > targetLength) {
130             //cut and may mask out
131             this.bitString = new byte[targetLength];
132             for (int i = 0; i < targetLength; i++) {
133                 //Copy defensive the bitString to this immutable object.
134                 this.bitString[i] = bitString[bitString.length-targetLength+i];
135             }
136             //Mask out left zero padding bits.
137             this.bitString[0] &= (0xff >>> ((8 - bitLength % 8) % 8));
138         }        
139         /*
140          * 3. In the third case the parameter bitString has the same length as
141          *    the member this.bitString[], that we got in dependence on the 
142          *    parameter bitLength. So we have nothing to fill with 0x00 or to 
143          *    cut. All we have to do is to mask out unused bits in 
144          *    this.bitString[0] in dependence of the parameter bitLength.
145          */        
146         else /*(bitString.length == targetLength)*/ {
147             //may mask out
148             //Copy defensive the bitString to this immutable object.
149             this.bitString = (byte[]) bitString.clone();
150             //Mask out left zero padding bits.
151             this.bitString[0] &= (0xff >>> ((8 - bitLength % 8) % 8));            
152         }
153         
154         //Copy the bitLength to this immutable object.        
155         this.bitLength = bitLength;
156     }
157     
158     
159     /** 
160      * Indicates whether some other object is "equal to" this one.
161      *
162      * @param   obj   the reference object with which to compare.
163      * @return  <code>true</code> if this object is the same as the obj
164      *         argument; <code>false</code> otherwise.
165      * @see     #hashCode()
166      * @see     java.util.Hashtable
167      */
168     public boolean equals(Object obj) {
169         //Only for performance.
170         if (this == obj) {
171             return true;
172         } 
173         
174         //If obj == null then instanceof returns false, see JLS 15.20.2
175         if (!(obj instanceof ISO9796Part1BitString)) {
176             return false;
177         }
178         
179         ISO9796Part1BitString other = (ISO9796Part1BitString)obj;
180         return Arrays.equals(this.bitString, other.bitString) &&
181                this.bitLength == other.bitLength;
182     }    
183     
184     /** 
185      * Returns a hash code value for the object. This method is
186      * supported for the benefit of hashtables such as those provided by
187      * <code>java.util.Hashtable</code>.
188      *
189      * @return  a hash code value for this object.
190      * @see     #equals(java.lang.Object)
191      * @see     java.util.Hashtable
192      */
193     public int hashCode() {
194         int result = 17;
195         for (int i = 0; i < this.bitString.length; i++) {
196             result = 37*result + this.bitString[i];
197         }
198         result = 37*result + this.bitLength;
199         return result;
200     }    
201     
202     /** 
203      * Returns a string representation of the object.
204      *
205      * @return  a string representation of the object.
206      */    
207     public String toString() {
208         return "[ISO9796Part1BitString bitString: " + 
209                ByteUtil.toHex(this.bitString) + 
210                " bitLength: " + 
211                this.bitLength + "]";
212     }
213 
214     /**
215      * Returns a copy of the internal bitString as byte array.
216      *
217      * @return a copy of the internal bitString . 
218      */
219     byte[] getBitString() {
220         return (byte[]) this.bitString.clone();
221     }
222     
223     /**
224      * Returns a copy of the length of the internal bitString in bit.
225      *
226      * @return a copy of the bitString length.
227      */
228     int getBitLength() {
229         return this.bitLength;
230     }
231 }
232