root / docs / www / colonyscout / internal / includes / uploadify / com / adobe / crypto / SHA1.as @ f59acf11
History | View | Annotate | Download (7.87 KB)
1 |
/* |
---|---|
2 |
Copyright (c) 2008, Adobe Systems Incorporated |
3 |
All rights reserved. |
4 |
|
5 |
Redistribution and use in source and binary forms, with or without |
6 |
modification, are permitted provided that the following conditions are |
7 |
met: |
8 |
|
9 |
* Redistributions of source code must retain the above copyright notice, |
10 |
this list of conditions and the following disclaimer. |
11 |
|
12 |
* Redistributions in binary form must reproduce the above copyright |
13 |
notice, this list of conditions and the following disclaimer in the |
14 |
documentation and/or other materials provided with the distribution. |
15 |
|
16 |
* Neither the name of Adobe Systems Incorporated nor the names of its |
17 |
contributors may be used to endorse or promote products derived from |
18 |
this software without specific prior written permission. |
19 |
|
20 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
21 |
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
22 |
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 |
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
24 |
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 |
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 |
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 |
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 |
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 |
*/ |
32 |
|
33 |
package com.adobe.crypto |
34 |
{ |
35 |
import com.adobe.utils.IntUtil; |
36 |
import flash.utils.ByteArray; |
37 |
import mx.utils.Base64Encoder; |
38 |
|
39 |
/** |
40 |
* US Secure Hash Algorithm 1 (SHA1) |
41 |
* |
42 |
* Implementation based on algorithm description at |
43 |
* http://www.faqs.org/rfcs/rfc3174.html |
44 |
*/ |
45 |
public class SHA1 |
46 |
{ |
47 |
public static var digest:ByteArray; |
48 |
|
49 |
/** |
50 |
* Performs the SHA1 hash algorithm on a string. |
51 |
* |
52 |
* @param s The string to hash |
53 |
* @return A string containing the hash value of s |
54 |
* @langversion ActionScript 3.0 |
55 |
* @playerversion 9.0 |
56 |
* @tiptext |
57 |
*/ |
58 |
public static function hash( s:String ):String |
59 |
{ |
60 |
var blocks:Array = createBlocksFromString( s ); |
61 |
var byteArray:ByteArray = hashBlocks( blocks ); |
62 |
|
63 |
return IntUtil.toHex( byteArray.readInt(), true ) |
64 |
+ IntUtil.toHex( byteArray.readInt(), true ) |
65 |
+ IntUtil.toHex( byteArray.readInt(), true ) |
66 |
+ IntUtil.toHex( byteArray.readInt(), true ) |
67 |
+ IntUtil.toHex( byteArray.readInt(), true ); |
68 |
} |
69 |
|
70 |
/** |
71 |
* Performs the SHA1 hash algorithm on a ByteArray. |
72 |
* |
73 |
* @param data The ByteArray data to hash |
74 |
* @return A string containing the hash value of data |
75 |
* @langversion ActionScript 3.0 |
76 |
* @playerversion 9.0 |
77 |
*/ |
78 |
public static function hashBytes( data:ByteArray ):String |
79 |
{ |
80 |
var blocks:Array = SHA1.createBlocksFromByteArray( data ); |
81 |
var byteArray:ByteArray = hashBlocks(blocks); |
82 |
|
83 |
return IntUtil.toHex( byteArray.readInt(), true ) |
84 |
+ IntUtil.toHex( byteArray.readInt(), true ) |
85 |
+ IntUtil.toHex( byteArray.readInt(), true ) |
86 |
+ IntUtil.toHex( byteArray.readInt(), true ) |
87 |
+ IntUtil.toHex( byteArray.readInt(), true ); |
88 |
} |
89 |
|
90 |
/** |
91 |
* Performs the SHA1 hash algorithm on a string, then does |
92 |
* Base64 encoding on the result. |
93 |
* |
94 |
* @param s The string to hash |
95 |
* @return The base64 encoded hash value of s |
96 |
* @langversion ActionScript 3.0 |
97 |
* @playerversion 9.0 |
98 |
* @tiptext |
99 |
*/ |
100 |
public static function hashToBase64( s:String ):String |
101 |
{ |
102 |
var blocks:Array = SHA1.createBlocksFromString( s ); |
103 |
var byteArray:ByteArray = hashBlocks(blocks); |
104 |
|
105 |
// ByteArray.toString() returns the contents as a UTF-8 string, |
106 |
// which we can't use because certain byte sequences might trigger |
107 |
// a UTF-8 conversion. Instead, we convert the bytes to characters |
108 |
// one by one. |
109 |
var charsInByteArray:String = ""; |
110 |
byteArray.position = 0; |
111 |
for (var j:int = 0; j < byteArray.length; j++) |
112 |
{ |
113 |
var byte:uint = byteArray.readUnsignedByte(); |
114 |
charsInByteArray += String.fromCharCode(byte); |
115 |
} |
116 |
|
117 |
var encoder:Base64Encoder = new Base64Encoder(); |
118 |
encoder.encode(charsInByteArray); |
119 |
return encoder.flush(); |
120 |
} |
121 |
|
122 |
private static function hashBlocks( blocks:Array ):ByteArray |
123 |
{ |
124 |
// initialize the h's |
125 |
var h0:int = 0x67452301; |
126 |
var h1:int = 0xefcdab89; |
127 |
var h2:int = 0x98badcfe; |
128 |
var h3:int = 0x10325476; |
129 |
var h4:int = 0xc3d2e1f0; |
130 |
|
131 |
var len:int = blocks.length; |
132 |
var w:Array = new Array( 80 ); |
133 |
|
134 |
// loop over all of the blocks |
135 |
for ( var i:int = 0; i < len; i += 16 ) { |
136 |
|
137 |
// 6.1.c |
138 |
var a:int = h0; |
139 |
var b:int = h1; |
140 |
var c:int = h2; |
141 |
var d:int = h3; |
142 |
var e:int = h4; |
143 |
|
144 |
// 80 steps to process each block |
145 |
// TODO: unroll for faster execution, or 4 loops of |
146 |
// 20 each to avoid the k and f function calls |
147 |
for ( var t:int = 0; t < 80; t++ ) { |
148 |
|
149 |
if ( t < 16 ) { |
150 |
// 6.1.a |
151 |
w[ t ] = blocks[ i + t ]; |
152 |
} else { |
153 |
// 6.1.b |
154 |
w[ t ] = IntUtil.rol( w[ t - 3 ] ^ w[ t - 8 ] ^ w[ t - 14 ] ^ w[ t - 16 ], 1 ); |
155 |
} |
156 |
|
157 |
// 6.1.d |
158 |
var temp:int = IntUtil.rol( a, 5 ) + f( t, b, c, d ) + e + int( w[ t ] ) + k( t ); |
159 |
|
160 |
e = d; |
161 |
d = c; |
162 |
c = IntUtil.rol( b, 30 ); |
163 |
b = a; |
164 |
a = temp; |
165 |
} |
166 |
|
167 |
// 6.1.e |
168 |
h0 += a; |
169 |
h1 += b; |
170 |
h2 += c; |
171 |
h3 += d; |
172 |
h4 += e; |
173 |
} |
174 |
|
175 |
var byteArray:ByteArray = new ByteArray(); |
176 |
byteArray.writeInt(h0); |
177 |
byteArray.writeInt(h1); |
178 |
byteArray.writeInt(h2); |
179 |
byteArray.writeInt(h3); |
180 |
byteArray.writeInt(h4); |
181 |
byteArray.position = 0; |
182 |
|
183 |
digest = new ByteArray(); |
184 |
digest.writeBytes(byteArray); |
185 |
digest.position = 0; |
186 |
return byteArray; |
187 |
} |
188 |
|
189 |
/** |
190 |
* Performs the logical function based on t |
191 |
*/ |
192 |
private static function f( t:int, b:int, c:int, d:int ):int { |
193 |
if ( t < 20 ) { |
194 |
return ( b & c ) | ( ~b & d ); |
195 |
} else if ( t < 40 ) { |
196 |
return b ^ c ^ d; |
197 |
} else if ( t < 60 ) { |
198 |
return ( b & c ) | ( b & d ) | ( c & d ); |
199 |
} |
200 |
return b ^ c ^ d; |
201 |
} |
202 |
|
203 |
/** |
204 |
* Determines the constant value based on t |
205 |
*/ |
206 |
private static function k( t:int ):int { |
207 |
if ( t < 20 ) { |
208 |
return 0x5a827999; |
209 |
} else if ( t < 40 ) { |
210 |
return 0x6ed9eba1; |
211 |
} else if ( t < 60 ) { |
212 |
return 0x8f1bbcdc; |
213 |
} |
214 |
return 0xca62c1d6; |
215 |
} |
216 |
|
217 |
/** |
218 |
* Converts a ByteArray to a sequence of 16-word blocks |
219 |
* that we'll do the processing on. Appends padding |
220 |
* and length in the process. |
221 |
* |
222 |
* @param data The data to split into blocks |
223 |
* @return An array containing the blocks into which data was split |
224 |
*/ |
225 |
private static function createBlocksFromByteArray( data:ByteArray ):Array |
226 |
{ |
227 |
var oldPosition:int = data.position; |
228 |
data.position = 0; |
229 |
|
230 |
var blocks:Array = new Array(); |
231 |
var len:int = data.length * 8; |
232 |
var mask:int = 0xFF; // ignore hi byte of characters > 0xFF |
233 |
for( var i:int = 0; i < len; i += 8 ) |
234 |
{ |
235 |
blocks[ i >> 5 ] |= ( data.readByte() & mask ) << ( 24 - i % 32 ); |
236 |
} |
237 |
|
238 |
// append padding and length |
239 |
blocks[ len >> 5 ] |= 0x80 << ( 24 - len % 32 ); |
240 |
blocks[ ( ( ( len + 64 ) >> 9 ) << 4 ) + 15 ] = len; |
241 |
|
242 |
data.position = oldPosition; |
243 |
|
244 |
return blocks; |
245 |
} |
246 |
|
247 |
/** |
248 |
* Converts a string to a sequence of 16-word blocks |
249 |
* that we'll do the processing on. Appends padding |
250 |
* and length in the process. |
251 |
* |
252 |
* @param s The string to split into blocks |
253 |
* @return An array containing the blocks that s was split into. |
254 |
*/ |
255 |
private static function createBlocksFromString( s:String ):Array |
256 |
{ |
257 |
var blocks:Array = new Array(); |
258 |
var len:int = s.length * 8; |
259 |
var mask:int = 0xFF; // ignore hi byte of characters > 0xFF |
260 |
for( var i:int = 0; i < len; i += 8 ) { |
261 |
blocks[ i >> 5 ] |= ( s.charCodeAt( i / 8 ) & mask ) << ( 24 - i % 32 ); |
262 |
} |
263 |
|
264 |
// append padding and length |
265 |
blocks[ len >> 5 ] |= 0x80 << ( 24 - len % 32 ); |
266 |
blocks[ ( ( ( len + 64 ) >> 9 ) << 4 ) + 15 ] = len; |
267 |
return blocks; |
268 |
} |
269 |
|
270 |
} |
271 |
} |