elcgit / s3-swf-upload-plugin

A rails plugin which allow user upload files to S3 through an embedded flash directly.

This URL has Read+Write access

Zhang Yuanyi (author)
Mon Nov 17 00:50:09 -0800 2008
b3432fb2 » Zhang Yuanyi 2008-11-17 initial commit 1 module S3SwfUpload
2 module Signature
3 $hexcase = false # hex output format. false - lowercase; true - uppercase
4 $b64pad = "=" # base-64 pad character. "=" for strict RFC compliance
5 $chrsz = 8 # bits per input character. 8 - ASCII; 16 - Unicode
6
7 def hex_sha1(s)
8 return binb2hex(core_sha1(str2binb(s), s.length * $chrsz))
9 end
10
11 def b64_hmac_sha1(key, data)
12 return binb2b64(core_hmac_sha1(key, data))
13 end
14
15 # Absolute barebones "unit" tests
16 def assert(expr)
17 raise 'Assertion failed' unless (expr)
18 end
19
20 def self_test
21 num, cnt = [1732584193, 5]
22
23 assert(core_sha1(str2binb('abc'), 'abc'.length) == [-519653305, -1566383753, -2070791546, -753729183, -204968198])
24 assert(rol(num, cnt) == -391880660)
25 assert(safe_add(2042729798, num) == -519653305)
26 assert((num.js_shl(cnt)) == -391880672)
27 assert((num.js_shr_zf(32 - cnt)) == 12)
28 assert(sha1_ft(0, -271733879, -1732584194, 271733878) == -1732584194)
29 assert(sha1_kt(0) == 1518500249)
30 assert(safe_add(safe_add(rol(num, cnt), sha1_ft(0, -271733879, -1732584194, 271733878)), safe_add(safe_add(-1009589776, 1902273280), sha1_kt(0))) == 286718899)
31 assert(str2binb('foo bar hey there') == [1718578976, 1650553376, 1751480608, 1952998770, 1694498816])
32 assert(hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d")
33 assert(b64_hmac_sha1("foo", "abc") == "frFXMR9cNoJdsSPnjebZpBhUKzI=")
34 end
35
36 # Calculate the SHA-1 of an array of big-endian words, and a bit length
37 def core_sha1(x, len)
38 # append padding
39 x[len >> 5] ||= 0
40 x[len >> 5] |= 0x80 << (24 - len % 32)
41 x[((len + 64 >> 9) << 4) + 15] = len
42
43 w = Array.new(80, 0)
44 a = 1732584193
45 b = -271733879
46 c = -1732584194
47 d = 271733878
48 e = -1009589776
49
50 #for(var i = 0; i < x.length; i += 16)
51 i = 0
52 while(i < x.length)
53 olda = a
54 oldb = b
55 oldc = c
56 oldd = d
57 olde = e
58
59 #for(var j = 0; j < 80; j++)
60 j = 0
61 while(j < 80)
62 if(j < 16)
63 w[j] = x[i + j] || 0
64 else
65 w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1)
66 end
67
68 t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
69 safe_add(safe_add(e, w[j]), sha1_kt(j)))
70 e = d
71 d = c
72 c = rol(b, 30)
73 b = a
74 a = t
75 j += 1
76 end
77
78 a = safe_add(a, olda)
79 b = safe_add(b, oldb)
80 c = safe_add(c, oldc)
81 d = safe_add(d, oldd)
82 e = safe_add(e, olde)
83 i += 16
84 end
85 return [a, b, c, d, e]
86 end
87
88 # Perform the appropriate triplet combination function for the current
89 # iteration
90 def sha1_ft(t, b, c, d)
91 return (b & c) | ((~b) & d) if(t < 20)
92 return b ^ c ^ d if(t < 40)
93 return (b & c) | (b & d) | (c & d) if(t < 60)
94 return b ^ c ^ d;
95 end
96
97 # Determine the appropriate additive constant for the current iteration
98 def sha1_kt(t)
99 return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
100 (t < 60) ? -1894007588 : -899497514
101 end
102
103 # Calculate the HMAC-SHA1 of a key and some data
104 def core_hmac_sha1(key, data)
105 bkey = str2binb(key)
106 if(bkey.length > 16)
107 bkey = core_sha1(bkey, key.length * $chrsz)
108 end
109
110 ipad = Array.new(16, 0)
111 opad = Array.new(16, 0)
112 #for(var i = 0; i < 16; i++)
113 i = 0
114 while(i < 16)
115 ipad[i] = (bkey[i] || 0) ^ 0x36363636
116 opad[i] = (bkey[i] || 0) ^ 0x5C5C5C5C
117 i += 1
118 end
119
120 hash = core_sha1((ipad + str2binb(data)), 512 + data.length * $chrsz)
121 return core_sha1((opad + hash), 512 + 160)
122 end
123
124 # Add integers, wrapping at 2^32. This uses 16-bit operations internally
125 # to work around bugs in some JS interpreters.
126 def safe_add(x, y)
127 v = (x+y) % (2**32)
128 return v > 2**31 ? v- 2**32 : v
129 end
130
131 # Bitwise rotate a 32-bit number to the left.
132 def rol(num, cnt)
133 #return (num << cnt) | (num >>> (32 - cnt))
134 return (num.js_shl(cnt)) | (num.js_shr_zf(32 - cnt))
135 end
136
137 # Convert an 8-bit or 16-bit string to an array of big-endian words
138 # In 8-bit function, characters >255 have their hi-byte silently ignored.
139 def str2binb(str)
140 bin = []
141 mask = (1 << $chrsz) - 1
142 #for(var i = 0; i < str.length * $chrsz; i += $chrsz)
143 i = 0
144 while(i < str.length * $chrsz)
145 bin[i>>5] ||= 0
146 bin[i>>5] |= (str[i / $chrsz] & mask) << (32 - $chrsz - i%32)
147 i += $chrsz
148 end
149 return bin
150 end
151
152 # Convert an array of big-endian words to a string
153 # function binb2str(bin)
154 # {
155 # var str = "";
156 # var mask = (1 << $chrsz) - 1;
157 # for(var i = 0; i < bin.length * 32; i += $chrsz)
158 # str += String.fromCharCode((bin[i>>5] >>> (32 - $chrsz - i%32)) & mask);
159 # return str;
160 # }
161 #
162
163 # Convert an array of big-endian words to a hex string.
164 def binb2hex(binarray)
165 hex_tab = $hexcase ? "0123456789ABCDEF" : "0123456789abcdef"
166 str = ""
167 #for(var i = 0; i < binarray.length * 4; i++)
168 i = 0
169 while(i < binarray.length * 4)
170 str += hex_tab[(binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF].chr +
171 hex_tab[(binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF].chr
172 i += 1
173 end
174 return str;
175 end
176
177 # Convert an array of big-endian words to a base-64 string
178 def binb2b64(binarray)
179 tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
180 str = ""
181
182 #for(var i = 0; i < binarray.length * 4; i += 3)
183 i = 0
184 while(i < binarray.length * 4)
185 triplet = (((binarray[i >> 2].to_i >> 8 * (3 - i %4)) & 0xFF) << 16) |
186 (((binarray[i+1 >> 2].to_i >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) |
187 ((binarray[i+2 >> 2].to_i >> 8 * (3 - (i+2)%4)) & 0xFF)
188 #for(var j = 0; j < 4; j++)
189 j = 0
190 while(j < 4)
191 if(i * 8 + j * 6 > binarray.length * 32)
192 str += $b64pad
193 else
194 str += tab[(triplet >> 6*(3-j)) & 0x3F].chr
195 end
196 j += 1
197 end
198 i += 3
199 end
200 return str
201 end
202 end
203 end