Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jsdsi/Hash.java


1   /*
2    * Copyright 2002 Massachusetts Institute of Technology
3    *   
4    * Permission to use, copy, modify, and distribute this program for any
5    * purpose and without fee is hereby granted, provided that this
6    * copyright and permission notice appear on all copies and supporting
7    * documentation, the name of M.I.T. not be used in advertising or
8    * publicity pertaining to distribution of the program without specific
9    * prior permission, and notice be given in supporting documentation that
10   * copying and distribution is by permission of M.I.T.  M.I.T. makes no
11   * representations about the suitability of this software for any
12   * purpose.  It is provided "as is" without express or implied warranty.
13   */
14  package jsdsi;
15  
16  import jsdsi.sexp.*;
17  import java.net.URL;
18  import java.security.MessageDigest;
19  import java.security.NoSuchAlgorithmException;
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  /**
25   * A cryptographic hash value.  Specifies the hash algorithm, the value
26   * to hash, and an optional set of URIs that specify where the hashed
27   * object is located.
28   * 
29   * @author Sameer Ajmani
30   * @version $Revision: 1.3 $ $Date: 2003/08/02 18:35:48 $
31   */
32  public class Hash extends Obj {
33    /**
34     * Name of the hash algorithm used.
35     */
36    private final String algo;
37  
38    /**
39     * Hash value.
40     */
41    private final byte[] data;
42  
43    /**
44     * URLs assigned to this <code>Hash</code> (may be <code>null</code>).
45     */
46    private final URL[] urls;
47  
48    /**
49     * Creates a new <code>Hash</code> from a given algorithm name, a 
50     * value to hash, and an array of URLs.
51     * 
52     * @param  a name of the hash algorithm used.
53     * @param  d value to hash.
54     * @param  u an array of URLs assigned to this <code>Hash</code>.
55     */
56    public Hash(String a, byte[] d, URL[] u) {
57      assert(a != null) : "null algo";
58      assert(d != null) : "null data";
59      algo = a;
60      data = d;
61      urls = u;
62    }
63  
64    /**
65     * Creates a new <code>Hash</code> from a given algorithm name, object
66     * to hash, and an array of URLs.
67     * 
68     * @param  a name of the hash algorithm used.
69     * @param  o object to calculate the hash value from.
70     * @param  u an array of URLs assigned to this <code>Hash</code>.
71     */
72    public Hash(String a, Obj o, URL[] u) {
73      assert(a != null) : "null algo";
74      assert(o != null) : "null object";
75      algo = a;
76      try {
77        data = MessageDigest.getInstance(a).digest(o.toByteArray());
78      } catch (NoSuchAlgorithmException e) {
79        throw new Error(e);
80      }
81      urls = u;
82    }
83  
84    /**
85     * Creates a new <code>Hash</code> from an algorithm name and a byte array
86     * that contains a hash value.
87     * 
88     * @param  a name of the hash algorithm used.
89     * @param  d byte array containing the value to hash.
90     */
91    public Hash(String a, byte[] d) {
92      this(a, d, null);
93    }
94  
95    /**
96     * Creates a new <code>Hash</code> from an algorithm name and an object.
97     * 
98     * @param  a name of the hash algorithm used.
99     * @param  o object to calculate the hash value from.
100    */
101   public Hash(String a, Obj o) {
102     this(a, o, null);
103   }
104 
105   /**
106    * Returns the name of the algorithm used.
107    * 
108    * @return the name of the algorithm used.
109    */
110   public String getAlgorithm() {
111     return algo;
112   }
113 
114   /**
115    * Returns the hash value as a byte array.
116    * 
117    * @return a byte array that stores the has value.
118    */
119   public byte[] getData() {
120     return data;
121   }
122 
123   /**
124    * Returns an array of URLs assigned to this <code>Hash</code>.
125    * 
126    * @return an array of URLs assigned to this <code>Hash</code>.
127    */
128   public URL[] getURLs() {
129     return urls;
130   }
131 
132   /**
133    * @see java.lang.Object#equals(Object)
134    */
135   public boolean equals(Object o) {
136     if (o instanceof Hash) {
137       Hash h = (Hash) o;
138       return algo.equals(h.algo)
139         && java.util.Arrays.equals(data, h.data)
140         && Util.equals(urls, h.urls);
141     }
142     return false;
143   }
144 
145   /**
146    * @see java.lang.Object#hashCode()
147    */
148   public int hashCode() {
149     return algo.hashCode() ^ data.hashCode() ^ Util.hashCode(urls);
150   }
151 
152   /**
153    * Returns an <code>SexpList</code> that holds this <code>Hash</code>.
154    * 
155    * @return an <code>SexpList</code> that holds this <code>Hash</code>.
156    */
157   public SexpList toSexp() {
158     List l = new ArrayList(3);
159     l.add(SexpUtil.toSexp(getAlgorithm()));
160     l.add(SexpUtil.toSexp(getData()));
161     if (getURLs() != null) {
162       l.add(SexpUtil.toSexp(getURLs()));
163     }
164     return SexpUtil.toSexp("hash", l);
165   }
166 
167   /**
168    * Parses an <code>SexpList</code> that holds a <code>Hash</code>
169    * and returns a <code>Hash</code> of this.
170    * 
171    * @param l the <code>SexpList</code> to parse.
172    * @return the <code>Hash</code> created from the 
173    *   <code>SexList</code>.
174    * @throws SexpParseException
175    */
176   public static Hash parseHash(SexpList l) throws SexpParseException {
177     Iterator hbody = SexpUtil.getBody(l);
178     String algo = SexpUtil.getNextString(hbody, "hash algo");
179     byte[] data = SexpUtil.getNextByteArray(hbody, "hash data");
180     SexpUtil.checkDone(hbody, "hash"); // TODO: support URIs
181     return new Hash(algo, data);
182   }
183 }