Source Code Cross Referenced for SHAOutputStream.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » luni » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.luni.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        package org.apache.harmony.luni.util;
019:
020:        import java.io.OutputStream;
021:
022:        /**
023:         * This class implements the Secure Hash Algorithm, SHA-1. The specification can
024:         * be found at http://csrc.ncsl.nist.gov/fips/fip180-1.txt
025:         */
026:        public class SHAOutputStream extends OutputStream implements  Cloneable {
027:
028:            /* Constants as in the specification */
029:
030:            // K in iterations 0..19, from spec
031:            private static final int K0_19 = 0x5a827999;
032:
033:            // K in iterations 20..39, from spec
034:            private static final int K20_39 = 0x6ed9eba1;
035:
036:            // K in iterations 40..59, from spec
037:            private static final int K40_59 = 0x8f1bbcdc;
038:
039:            // K in iterations 60..79, from spec
040:            private static final int K60_79 = 0xca62c1d6;
041:
042:            // H0, from spec
043:            private static final int H0 = 0x67452301;
044:
045:            // H1, from spec
046:            private static final int H1 = 0xefcdab89;
047:
048:            // H2, from spec
049:            private static final int H2 = 0x98badcfe;
050:
051:            // H3, from spec
052:            private static final int H3 = 0x10325476;
053:
054:            // H4, from spec
055:            private static final int H4 = 0xc3d2e1f0;
056:
057:            private static final int HConstantsSize = 5;
058:
059:            private static final int HashSizeInBytes = 20;
060:
061:            // 16 words
062:            private static final int BlockSizeInBytes = 16 * 4;
063:
064:            // 80 words
065:            private static final int WArraySize = 80;
066:
067:            // 5-word Array. Starts with well-known constants, ends with SHA
068:            private int[] HConstants;
069:
070:            // 80-word Array.
071:            private int[] WArray;
072:
073:            // 16-word Array. Input bit stream M is divided in chunks of MArray
074:            private byte[] MArray;
075:
076:            // Number of bytes of input already processed towards SHA result
077:            private long bytesProcessed;
078:
079:            // Number of bytes in WArray not processed yet
080:            private int bytesToProcess;
081:
082:            // Optimization, for write
083:            private byte[] oneByte = new byte[1];
084:
085:            /**
086:             * Constructs a new SHAOutputStream.
087:             */
088:            public SHAOutputStream() {
089:                super ();
090:                initialize();
091:                reset();
092:            }
093:
094:            /**
095:             * Constructs a new MD5OutputStream with the given initial state.
096:             * 
097:             * @param state The initial state of the output stream. This is what will be
098:             *        returned by getHash() if write() is never called.
099:             * 
100:             * @throws IllegalArgumentException if state.length is less than 16.
101:             */
102:            public SHAOutputStream(byte[] state) {
103:                this ();
104:
105:                if (state.length < HashSizeInBytes) {
106:                    throw new IllegalArgumentException();
107:                }
108:
109:                for (int i = 0; i < 4; i++) {
110:                    HConstants[i] = 0;
111:                    for (int j = 0; j < 4; j++) {
112:                        HConstants[i] += (state[4 * i + j] & 0xFF) << 8 * (3 - j);
113:                    }
114:                }
115:            }
116:
117:            /**
118:             * Answers a new instance of the same class as the receiver, whose slots
119:             * have been filled in with the values in the slots of the receiver.
120:             * <p>
121:             * Classes which wish to support cloning must specify that they implement
122:             * the Cloneable interface, since the native implementation checks for this.
123:             * 
124:             * @return a complete copy of this object
125:             * @throws CloneNotSupportedException if the component does not implement
126:             *         the interface Cloneable
127:             */
128:            @Override
129:            public Object clone() throws CloneNotSupportedException {
130:                // Calling super takes care of primitive type slots
131:                SHAOutputStream result = (SHAOutputStream) super .clone();
132:                result.HConstants = this .HConstants.clone();
133:                result.WArray = this .WArray.clone();
134:                result.MArray = this .MArray.clone();
135:                result.oneByte = this .oneByte.clone();
136:                return result;
137:            }
138:
139:            /**
140:             * Copies a byte array into the receiver's internal buffer, making the
141:             * adjustments as necessary and keeping the receiver in a consistent state.
142:             * 
143:             * @param buffer byte array representation of the bytes
144:             * @param off offset into the source buffer where to start the copying
145:             * @param len how many bytes in the source byte array to copy
146:             * 
147:             */
148:            private void copyToInternalBuffer(byte[] buffer, int off, int len) {
149:                int index;
150:                index = off;
151:                for (int i = bytesToProcess; i < bytesToProcess + len; i++) {
152:                    MArray[i] = buffer[index];
153:                    index++;
154:                }
155:                bytesToProcess = bytesToProcess + len;
156:            }
157:
158:            /**
159:             * Returns an int array (length = 5) with the SHA value of the bytes written
160:             * to the receiver.
161:             * 
162:             * @return The 5 ints that form the SHA value of the bytes written to
163:             *         the receiver
164:             */
165:            public int[] getHash() {
166:                this .padBuffer();
167:                this .processBuffer();
168:                int[] result = HConstants.clone();
169:                // After the user asks for the hash value, the stream is put back to the
170:                // initial state
171:                reset();
172:                return result;
173:            }
174:
175:            /**
176:             * Returns a byte array (length = 20) with the SHA value of the bytes
177:             * written to the receiver.
178:             * 
179:             * @return The bytes that form the SHA value of the bytes written to
180:             *         the receiver
181:             */
182:            public byte[] getHashAsBytes() {
183:                byte[] hash = new byte[HashSizeInBytes];
184:                this .padBuffer();
185:                this .processBuffer();
186:
187:                // We need to return HConstants (modified by the loop) as an array of
188:                // bytes. A memcopy would be the fastest.
189:                for (int i = 0; i < (HashSizeInBytes / 4); ++i) {
190:                    hash[i * 4] = (byte) (HConstants[i] >>> 24 & 0xff);
191:                    hash[i * 4 + 1] = (byte) (HConstants[i] >>> 16 & 0xff);
192:                    hash[i * 4 + 2] = (byte) (HConstants[i] >>> 8 & 0xff);
193:                    hash[i * 4 + 3] = (byte) (HConstants[i] & 0xff);
194:                }
195:                // After the user asks for the hash value, the stream is put back to the
196:                // initial state
197:                reset();
198:                return hash;
199:            }
200:
201:            /**
202:             * Returns a byte array (length = 20) with the SHA value of the bytes
203:             * written to the receiver.
204:             * 
205:             * @return The bytes that form the SHA value of the bytes written to
206:             *         the receiver
207:             */
208:            public byte[] getHashAsBytes(boolean pad) {
209:                byte[] hash = new byte[HashSizeInBytes];
210:                if (pad) {
211:                    this .padBuffer();
212:                    this .processBuffer();
213:                }
214:
215:                // Convert HConstants to an array of bytes
216:                for (int i = 0; i < (HashSizeInBytes / 4); i++) {
217:                    hash[i * 4] = (byte) (HConstants[i] >>> 24 & 0xff);
218:                    hash[i * 4 + 1] = (byte) (HConstants[i] >>> 16 & 0xff);
219:                    hash[i * 4 + 2] = (byte) (HConstants[i] >>> 8 & 0xff);
220:                    hash[i * 4 + 3] = (byte) (HConstants[i] & 0xff);
221:                }
222:                // After the user asks for the hash value, the stream is put back to the
223:                // initial state
224:                reset();
225:                return hash;
226:            }
227:
228:            /**
229:             * Initializes the receiver.
230:             */
231:            private void initialize() {
232:                HConstants = new int[HConstantsSize];
233:                MArray = new byte[BlockSizeInBytes];
234:                WArray = new int[WArraySize];
235:            }
236:
237:            /**
238:             * Adds extra bytes to the bit stream as required (see the SHA
239:             * specification).
240:             */
241:            private void padBuffer() {
242:                long lengthInBits;
243:                MArray[bytesToProcess] = (byte) 0x80;
244:                for (int i = bytesToProcess + 1; i < BlockSizeInBytes; i++) {
245:                    MArray[i] = (byte) 0;
246:                }
247:                // Get length now because there might be extra padding (length in bits)
248:                lengthInBits = (bytesToProcess + bytesProcessed) * 8;
249:
250:                // 9 extra bytes are needed: 1 for 1000... and 8 for length (long)
251:                if ((bytesToProcess + 9) > BlockSizeInBytes) {
252:                    // Not enough space to append length. We need another block for
253:                    // padding
254:                    // Padding in this buffer only includes 1000000....
255:                    this .processBuffer();
256:                    // Now put 0's in all the buffer. memfill would be faster
257:                    for (int i = 0; i < BlockSizeInBytes; i++) {
258:                        MArray[i] = (byte) 0;
259:                    }
260:                }
261:
262:                for (int i = 1; i < 9; i++) {
263:                    MArray[BlockSizeInBytes - i] = (byte) (lengthInBits & 0xff);
264:                    lengthInBits = lengthInBits >>> 8;
265:                }
266:            }
267:
268:            /**
269:             * Core SHA code. Processes the receiver's buffer of bits, computing the
270:             * values towards the final SHA
271:             */
272:            private void processBuffer() {
273:                int A; // A variable, from spec
274:                int B; // B variable, from spec
275:                int C; // C variable, from spec
276:                int D; // D variable, from spec
277:                int E; // E variable, from spec
278:                int temp; // TEMP, from spec
279:                int t; // t, for iteration, from spec
280:
281:                for (t = 0; t <= 15; t++) { // step a, page 7 of spec. Here we convert 4
282:                    // bytes into 1 word, 16 times
283:                    WArray[t] = (MArray[4 * t] & 0xff) << 24
284:                            | ((MArray[4 * t + 1] & 0xff) << 16)
285:                            | ((MArray[4 * t + 2] & 0xff) << 8)
286:                            | (MArray[4 * t + 3] & 0xff);
287:                }
288:                for (t = 16; t <= 79; t++) { // step b, page 7 of spec
289:                    temp = (WArray[t - 3] ^ WArray[t - 8] ^ WArray[t - 14] ^ WArray[t - 16]);
290:                    temp = (temp << 1) | (temp >>> (32 - 1)); // element , Circular
291:                    // Shift Left by 1
292:                    WArray[t] = temp;
293:                }
294:
295:                // step c, page 7 of spec
296:                A = HConstants[0];
297:                B = HConstants[1];
298:                C = HConstants[2];
299:                D = HConstants[3];
300:                E = HConstants[4];
301:
302:                // step d, page 8 of spec
303:                for (t = 0; t <= 19; t++) {
304:                    temp = (A << 5) | (A >>> (32 - 5)); // A , Circular Shift Left by 5
305:                    temp = temp + E + WArray[t] + K0_19;
306:                    temp = temp + ((B & C) | (~B & D));
307:                    E = D;
308:                    D = C;
309:                    C = (B << 30) | (B >>> (32 - 30)); // B , Circular Shift Left by 30
310:                    B = A;
311:                    A = temp;
312:                }
313:                for (t = 20; t <= 39; t++) {
314:                    temp = (A << 5) | (A >>> (32 - 5)); // A , Circular Shift Left by 5
315:                    temp = temp + E + WArray[t] + K20_39;
316:                    temp = temp + (B ^ C ^ D);
317:                    E = D;
318:                    D = C;
319:                    C = (B << 30) | (B >>> (32 - 30)); // B , Circular Shift Left by 30
320:                    B = A;
321:                    A = temp;
322:                }
323:                for (t = 40; t <= 59; t++) {
324:                    temp = (A << 5) | (A >>> (32 - 5)); // A , Circular Shift Left by 5
325:                    temp = temp + E + WArray[t] + K40_59;
326:                    temp = temp + ((B & C) | (B & D) | (C & D));
327:                    E = D;
328:                    D = C;
329:                    C = (B << 30) | (B >>> (32 - 30)); // B , Circular Shift Left by 30
330:                    B = A;
331:                    A = temp;
332:                }
333:                for (t = 60; t <= 79; t++) {
334:                    temp = (A << 5) | (A >>> (32 - 5)); // A , Circular Shift Left by 5
335:                    temp = temp + E + WArray[t] + K60_79;
336:                    temp = temp + (B ^ C ^ D);
337:                    E = D;
338:                    D = C;
339:                    C = (B << 30) | (B >>> (32 - 30)); // B , Circular Shift Left by 30
340:                    B = A;
341:                    A = temp;
342:                }
343:
344:                // step e, page 8 of spec
345:                HConstants[0] = HConstants[0] + A;
346:                HConstants[1] = HConstants[1] + B;
347:                HConstants[2] = HConstants[2] + C;
348:                HConstants[3] = HConstants[3] + D;
349:                HConstants[4] = HConstants[4] + E;
350:                // Update number of bytes actually processed
351:                bytesProcessed = bytesProcessed + BlockSizeInBytes;
352:                bytesToProcess = 0; // No pending bytes in the block
353:
354:            }
355:
356:            /**
357:             * Reset this SHAOutputStream to the state it was before any byte was
358:             * written to it.
359:             */
360:            public void reset() {
361:                HConstants[0] = H0;
362:                HConstants[1] = H1;
363:                HConstants[2] = H2;
364:                HConstants[3] = H3;
365:                HConstants[4] = H4;
366:                bytesProcessed = 0;
367:                bytesToProcess = 0;
368:            }
369:
370:            @Override
371:            public String toString() {
372:                return this .getClass().getName() + ':'
373:                        + toStringBlock(getHashAsBytes());
374:            }
375:
376:            /**
377:             * Converts a block to a String representation.
378:             * 
379:             * @param block
380:             *            byte array representation of the bytes
381:             */
382:            private static String toStringBlock(byte[] block) {
383:                return toStringBlock(block, 0, block.length);
384:            }
385:
386:            /**
387:             * Converts a block to a String representation.
388:             * 
389:             * @param block
390:             *            byte array representation of the bytes
391:             * @param off
392:             *            offset into the block where to start the conversion
393:             * @param len
394:             *            how many bytes in the byte array to convert to a printable
395:             *            representation
396:             */
397:            private static String toStringBlock(byte[] block, int off, int len) {
398:                String hexdigits = "0123456789ABCDEF";
399:                StringBuilder buf = new StringBuilder();
400:                buf.append('[');
401:                for (int i = off; i < off + len; ++i) {
402:                    buf.append(hexdigits.charAt((block[i] >>> 4) & 0xf));
403:                    buf.append(hexdigits.charAt(block[i] & 0xf));
404:                }
405:                buf.append(']');
406:                return buf.toString();
407:            }
408:
409:            /**
410:             * Writes <code>len</code> <code>bytes</code> from this byte array
411:             * <code>buffer</code> starting at offset <code>off</code> to the
412:             * SHAOutputStream. The internal buffer used to compute SHA is updated, and
413:             * the incremental computation of SHA is also performed.
414:             * 
415:             * @param buffer
416:             *            the buffer to be written
417:             * @param off
418:             *            offset in buffer to get bytes
419:             * @param len
420:             *            number of bytes in buffer to write
421:             */
422:            @Override
423:            public void write(byte[] buffer, int off, int len) {
424:                int spaceLeft;
425:                int start;
426:                int bytesLeft;
427:                spaceLeft = BlockSizeInBytes - bytesToProcess;
428:                if (len < spaceLeft) { // Extra bytes are not enough to fill buffer
429:                    this .copyToInternalBuffer(buffer, off, len);
430:                    return;
431:                }
432:                // Extra bytes are bigger than space in buffer. Process buffer multiple
433:                // times
434:                this .copyToInternalBuffer(buffer, off, spaceLeft);
435:                bytesLeft = len - spaceLeft;
436:                this .processBuffer();
437:                start = off + spaceLeft;
438:                while (bytesLeft >= BlockSizeInBytes) {
439:                    this .copyToInternalBuffer(buffer, start, BlockSizeInBytes);
440:                    bytesLeft = bytesLeft - BlockSizeInBytes;
441:                    this .processBuffer();
442:                    start = start + BlockSizeInBytes;
443:                }
444:                if (bytesLeft > 0) {
445:                    // Extra bytes at the end, not enough to fill buffer
446:                    this .copyToInternalBuffer(buffer, start, bytesLeft);
447:                }
448:            }
449:
450:            /**
451:             * Writes the specified byte <code>b</code> to this OutputStream. Only the
452:             * low order byte of <code>b</code> is written.
453:             * 
454:             * @param b
455:             *            the byte to be written
456:             */
457:            @Override
458:            public void write(int b) {
459:                // Not thread-safe because we use a shared one-byte buffer
460:                oneByte[0] = (byte) b;
461:                write(oneByte, 0, 1);
462:            }
463:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.