condo 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.textile +133 -133
- data/app/assets/javascripts/condo.js +9 -6
- data/app/assets/javascripts/condo/amazon.js +403 -406
- data/app/assets/javascripts/condo/condo.js +184 -0
- data/app/assets/javascripts/condo/config.js +69 -80
- data/app/assets/javascripts/condo/google.js +338 -255
- data/app/assets/javascripts/condo/md5/hash.worker.emulator.js +23 -23
- data/app/assets/javascripts/condo/md5/hash.worker.js +11 -11
- data/app/assets/javascripts/condo/md5/hasher.js +119 -100
- data/app/assets/javascripts/condo/md5/spark-md5.js +276 -161
- data/app/assets/javascripts/condo/rackspace.js +326 -329
- data/app/assets/javascripts/condo/{abstract-md5.js.erb → services/abstract-md5.js.erb} +86 -93
- data/app/assets/javascripts/condo/{base64.js → services/base64.js} +2 -10
- data/app/assets/javascripts/condo/services/broadcaster.js +26 -0
- data/app/assets/javascripts/condo/services/uploader.js +302 -0
- data/app/assets/javascripts/core/core.js +4 -0
- data/app/assets/javascripts/core/services/1-safe-apply.js +17 -0
- data/app/assets/javascripts/core/services/2-messaging.js +171 -0
- data/lib/condo.rb +269 -269
- data/lib/condo/configuration.rb +137 -139
- data/lib/condo/errors.rb +8 -8
- data/lib/condo/strata/amazon_s3.rb +301 -301
- data/lib/condo/strata/google_cloud_storage.rb +315 -314
- data/lib/condo/strata/rackspace_cloud_files.rb +245 -223
- data/lib/condo/version.rb +1 -1
- metadata +21 -44
- data/app/assets/javascripts/condo/broadcaster.js +0 -60
- data/app/assets/javascripts/condo/controller.js +0 -194
- data/app/assets/javascripts/condo/uploader.js +0 -310
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +0 -25
@@ -1,23 +1,23 @@
|
|
1
|
-
//= require condo/md5/spark-md5
|
2
|
-
//= require condo/md5/hasher
|
3
|
-
|
4
|
-
|
5
|
-
function CondoHashWorkerEmulator(callback) {
|
6
|
-
|
7
|
-
// Create an API that looks like postMessage
|
8
|
-
this.postMessage = function (data, portArray) {
|
9
|
-
hasher.hash(data); // Clone the data if required JSON.parse(JSON.stringify(message)); // - Don't think it is required
|
10
|
-
}
|
11
|
-
|
12
|
-
|
13
|
-
this.terminate = function () {
|
14
|
-
// No special clean-up needed.
|
15
|
-
}
|
16
|
-
|
17
|
-
function messageEvtEmulator(rawMessage) {
|
18
|
-
callback({ data: rawMessage });
|
19
|
-
}
|
20
|
-
|
21
|
-
// Create an instance of downloader.
|
22
|
-
var hasher = new CondoMD5Hasher(messageEvtEmulator);
|
23
|
-
}
|
1
|
+
//= require condo/md5/spark-md5
|
2
|
+
//= require condo/md5/hasher
|
3
|
+
|
4
|
+
|
5
|
+
function CondoHashWorkerEmulator(callback) {
|
6
|
+
|
7
|
+
// Create an API that looks like postMessage
|
8
|
+
this.postMessage = function (data, portArray) {
|
9
|
+
hasher.hash(data); // Clone the data if required JSON.parse(JSON.stringify(message)); // - Don't think it is required
|
10
|
+
}
|
11
|
+
|
12
|
+
|
13
|
+
this.terminate = function () {
|
14
|
+
// No special clean-up needed.
|
15
|
+
}
|
16
|
+
|
17
|
+
function messageEvtEmulator(rawMessage) {
|
18
|
+
callback({ data: rawMessage });
|
19
|
+
}
|
20
|
+
|
21
|
+
// Create an instance of downloader.
|
22
|
+
var hasher = new CondoMD5Hasher(messageEvtEmulator, false);
|
23
|
+
}
|
@@ -1,11 +1,11 @@
|
|
1
|
-
//= require condo/md5/spark-md5
|
2
|
-
//= require condo/md5/hasher
|
3
|
-
|
4
|
-
|
5
|
-
var hasher = new CondoMD5Hasher(postMessage); // Accepts the callback as the parameter
|
6
|
-
|
7
|
-
|
8
|
-
// Hook-up worker input
|
9
|
-
onmessage = function (e) {
|
10
|
-
hasher.hash(e.data);
|
11
|
-
}
|
1
|
+
//= require condo/md5/spark-md5
|
2
|
+
//= require condo/md5/hasher
|
3
|
+
|
4
|
+
|
5
|
+
var hasher = new CondoMD5Hasher(postMessage, true); // Accepts the callback as the parameter
|
6
|
+
|
7
|
+
|
8
|
+
// Hook-up worker input
|
9
|
+
onmessage = function (e) {
|
10
|
+
hasher.hash(e.data);
|
11
|
+
};
|
@@ -1,100 +1,119 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
var CondoMD5Hasher = (function(global) {
|
4
|
-
|
5
|
-
var part_size = 1048576, // This is the amount of the file we read into memory as we are building the hash (1mb)
|
6
|
-
async = true
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
//
|
11
|
-
//
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
//
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
//
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
if
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
}
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
}
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
}
|
100
|
-
|
1
|
+
|
2
|
+
|
3
|
+
var CondoMD5Hasher = (function(global) {
|
4
|
+
|
5
|
+
var part_size = 1048576, // This is the amount of the file we read into memory as we are building the hash (1mb)
|
6
|
+
async = true,
|
7
|
+
newReader = !!navigator.userAgent.toLowerCase().match(/opera/); // Opera bug (opera can only use a reader once)
|
8
|
+
|
9
|
+
|
10
|
+
//
|
11
|
+
// Firefox does not have FileReader in webworkers? WTF
|
12
|
+
// See issue #2
|
13
|
+
//
|
14
|
+
if (!!!global.FileReader) {
|
15
|
+
async = false;
|
16
|
+
global.FileReader = global.FileReaderSync;
|
17
|
+
}
|
18
|
+
|
19
|
+
//
|
20
|
+
// Some browsers have a vendor prefix on slice
|
21
|
+
//
|
22
|
+
if (!!!Blob.prototype.slice) {
|
23
|
+
Blob.prototype.slice = Blob.prototype.webkitSlice || Blob.prototype.mozSlice;
|
24
|
+
}
|
25
|
+
|
26
|
+
return function(callback, inWorker) {
|
27
|
+
|
28
|
+
|
29
|
+
//
|
30
|
+
// Opera claims to have async readers in webworkers however it is actually just
|
31
|
+
// a synchronous reader in disguise
|
32
|
+
//
|
33
|
+
if (newReader && inWorker) {
|
34
|
+
async = false;
|
35
|
+
global.FileReader = global.FileReaderSync || global.FileReader;
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
//
|
40
|
+
// responds with: {success: true|false, result: <Object>}
|
41
|
+
//
|
42
|
+
this.hash = function(blob) {
|
43
|
+
|
44
|
+
var current_part,
|
45
|
+
md5 = new global.SparkMD5.ArrayBuffer(),
|
46
|
+
part_number = 0,
|
47
|
+
length = Math.ceil(blob.size / part_size),
|
48
|
+
reader,
|
49
|
+
|
50
|
+
fail = function() {
|
51
|
+
callback({
|
52
|
+
success: false,
|
53
|
+
result: 'file read failed'
|
54
|
+
});
|
55
|
+
},
|
56
|
+
|
57
|
+
hashData = function(e) {
|
58
|
+
md5.append(e.target.result);
|
59
|
+
if(part_number * part_size >= blob.size) {
|
60
|
+
callback({
|
61
|
+
success: true,
|
62
|
+
result: md5.end()
|
63
|
+
});
|
64
|
+
} else {
|
65
|
+
if (newReader) configureReader();
|
66
|
+
processPart();
|
67
|
+
}
|
68
|
+
},
|
69
|
+
|
70
|
+
processPart = function() {
|
71
|
+
var endbyte = 0;
|
72
|
+
|
73
|
+
part_number += 1;
|
74
|
+
|
75
|
+
if (blob.size > part_size) { // If blob bigger then part_size we will slice it up
|
76
|
+
endbyte = part_number * part_size;
|
77
|
+
if (endbyte > blob.size)
|
78
|
+
endbyte = blob.size;
|
79
|
+
|
80
|
+
current_part = blob.slice((part_number - 1) * part_size, endbyte);
|
81
|
+
} else {
|
82
|
+
current_part = blob;
|
83
|
+
}
|
84
|
+
|
85
|
+
if(async)
|
86
|
+
reader.readAsArrayBuffer(current_part);
|
87
|
+
else {
|
88
|
+
setTimeout(function() {
|
89
|
+
try {
|
90
|
+
hashData({
|
91
|
+
target: {
|
92
|
+
result: reader.readAsArrayBuffer(current_part)
|
93
|
+
}
|
94
|
+
});
|
95
|
+
} catch (e) {
|
96
|
+
fail();
|
97
|
+
}
|
98
|
+
}, 0);
|
99
|
+
}
|
100
|
+
|
101
|
+
},
|
102
|
+
|
103
|
+
configureReader = function() {
|
104
|
+
reader = new global.FileReader();
|
105
|
+
if(async) {
|
106
|
+
reader.onload = hashData;
|
107
|
+
reader.onerror = fail;
|
108
|
+
reader.onabort = fail;
|
109
|
+
}
|
110
|
+
};
|
111
|
+
|
112
|
+
|
113
|
+
configureReader();
|
114
|
+
processPart();
|
115
|
+
};
|
116
|
+
};
|
117
|
+
|
118
|
+
})(this);
|
119
|
+
|
@@ -1,83 +1,6 @@
|
|
1
1
|
/*jshint bitwise:false*/
|
2
2
|
/*global unescape*/
|
3
3
|
|
4
|
-
/**
|
5
|
-
* SparkMD5 is a fast md5 implementation of the MD5 algorithm.
|
6
|
-
* This script is based in the JKM md5 library which is the
|
7
|
-
* fastest algorithm around (see: http://jsperf.com/md5-shootout/7).
|
8
|
-
*
|
9
|
-
* NOTE: Please disable Firebug while testing this script!
|
10
|
-
* Firebug consumes a lot of memory and CPU and slows down by a great margin.
|
11
|
-
* Opera Dragonfly also slows down by a great margin.
|
12
|
-
* Safari/Chrome developer tools seems not to slow it down.
|
13
|
-
*
|
14
|
-
* Improvements over the JKM md5 library:
|
15
|
-
*
|
16
|
-
* - Functionality wrapped in a closure
|
17
|
-
* - Object oriented library
|
18
|
-
* - Incremental md5 (see bellow)
|
19
|
-
* - Validates using jslint
|
20
|
-
*
|
21
|
-
* Incremental md5 performs a lot better for hashing large ammounts of data, such as
|
22
|
-
* files. One could read files in chunks, using the FileReader & Blob's, and append
|
23
|
-
* each chunk for md5 hashing while keeping memory usage low. See example bellow.
|
24
|
-
*
|
25
|
-
* @example
|
26
|
-
*
|
27
|
-
* Normal usage:
|
28
|
-
*
|
29
|
-
* var hexHash = SparkMD5.hash('Hi there'); // hex hash
|
30
|
-
* var rawHash = SparkMD5.hash('Hi there', true); // raw hash
|
31
|
-
*
|
32
|
-
* Incremental usage:
|
33
|
-
*
|
34
|
-
* var spark = new SparkMD5();
|
35
|
-
* spark.append('Hi');
|
36
|
-
* spark.append(' there');
|
37
|
-
* var hexHash = spark.end(); // hex hash
|
38
|
-
* var rawHash = spark.end(true); // raw hash
|
39
|
-
*
|
40
|
-
* Hash a file incrementally:
|
41
|
-
*
|
42
|
-
* NOTE: If you test the code bellow using the file:// protocol in chrome you must start the browser with -allow-file-access-from-files argument.
|
43
|
-
* Please see: http://code.google.com/p/chromium/issues/detail?id=60889
|
44
|
-
*
|
45
|
-
* document.getElementById("file").addEventListener("change", function() {
|
46
|
-
*
|
47
|
-
* var fileReader = new FileReader(),
|
48
|
-
* blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
|
49
|
-
* file = document.getElementById("file").files[0],
|
50
|
-
* chunkSize = 2097152, // read in chunks of 2MB
|
51
|
-
* chunks = Math.ceil(file.size / chunkSize),
|
52
|
-
* currentChunk = 0,
|
53
|
-
* spark = new SparkMD5();
|
54
|
-
*
|
55
|
-
* fileReader.onload = function(e) {
|
56
|
-
* console.log("read chunk nr", currentChunk + 1, "of", chunks);
|
57
|
-
* spark.appendBinary(e.target.result); // append binary string
|
58
|
-
* currentChunk++;
|
59
|
-
*
|
60
|
-
* if (currentChunk < chunks) {
|
61
|
-
* loadNext();
|
62
|
-
* }
|
63
|
-
* else {
|
64
|
-
* console.log("finished loading");
|
65
|
-
* console.info("computed hash", spark.end()); // compute hash
|
66
|
-
* }
|
67
|
-
* };
|
68
|
-
*
|
69
|
-
* function loadNext() {
|
70
|
-
* var start = currentChunk * chunkSize,
|
71
|
-
* end = start + chunkSize >= file.size ? file.size : start + chunkSize;
|
72
|
-
*
|
73
|
-
* fileReader.readAsBinaryString(blobSlice.call(file, start, end));
|
74
|
-
* };
|
75
|
-
*
|
76
|
-
* loadNext();
|
77
|
-
* });
|
78
|
-
*
|
79
|
-
* @TODO: Add native support for reading files? Maybe add it as an extension?
|
80
|
-
*/
|
81
4
|
(function (factory) {
|
82
5
|
if (typeof exports === 'object') {
|
83
6
|
// Node/CommonJS
|
@@ -99,32 +22,6 @@
|
|
99
22
|
}(function (undefined) {
|
100
23
|
|
101
24
|
'use strict';
|
102
|
-
|
103
|
-
|
104
|
-
/* converts strings to array buffers
|
105
|
-
* From: http://updates.html5rocks.com/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
|
106
|
-
*/
|
107
|
-
var str2ab = function (str) {
|
108
|
-
var buf = new ArrayBuffer(str.length * 2), // 2 bytes for each char
|
109
|
-
bufView = new Uint16Array(buf);
|
110
|
-
for (var i = 0, strLen = str.length; i < strLen; i++) {
|
111
|
-
bufView[i] = str.charCodeAt(i);
|
112
|
-
}
|
113
|
-
return buf;
|
114
|
-
},
|
115
|
-
|
116
|
-
|
117
|
-
abConcat = function(first, second)
|
118
|
-
{
|
119
|
-
var firstLength = first.length,
|
120
|
-
result = new Uint8Array(firstLength + second.byteLength);
|
121
|
-
|
122
|
-
result.set(first);
|
123
|
-
result.set(new Uint8Array(second), firstLength);
|
124
|
-
|
125
|
-
return result;
|
126
|
-
},
|
127
|
-
|
128
25
|
|
129
26
|
////////////////////////////////////////////////////////////////////////////
|
130
27
|
|
@@ -135,8 +32,13 @@
|
|
135
32
|
* @see http://www.myersdaily.org/joseph/javascript/md5-text.html
|
136
33
|
* @see http://jsperf.com/md5-shootout/7
|
137
34
|
*/
|
138
|
-
|
139
|
-
|
35
|
+
|
36
|
+
/* this function is much faster,
|
37
|
+
so if possible we use it. Some IEs
|
38
|
+
are the only ones I know of that
|
39
|
+
need the idiotic second function,
|
40
|
+
generated by an if clause. */
|
41
|
+
var add32 = function (a, b) {
|
140
42
|
return (a + b) & 0xFFFFFFFF;
|
141
43
|
},
|
142
44
|
|
@@ -145,23 +47,23 @@
|
|
145
47
|
return add32((a << s) | (a >>> (32 - s)), b);
|
146
48
|
},
|
147
49
|
|
148
|
-
ff = function(a, b, c, d, x, s, t) {
|
50
|
+
ff = function (a, b, c, d, x, s, t) {
|
149
51
|
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
150
52
|
},
|
151
53
|
|
152
|
-
gg = function(a, b, c, d, x, s, t) {
|
54
|
+
gg = function (a, b, c, d, x, s, t) {
|
153
55
|
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
154
56
|
},
|
155
57
|
|
156
|
-
hh = function(a, b, c, d, x, s, t) {
|
58
|
+
hh = function (a, b, c, d, x, s, t) {
|
157
59
|
return cmn(b ^ c ^ d, a, b, x, s, t);
|
158
60
|
},
|
159
61
|
|
160
|
-
ii = function(a, b, c, d, x, s, t) {
|
62
|
+
ii = function (a, b, c, d, x, s, t) {
|
161
63
|
return cmn(c ^ (b | (~d)), a, b, x, s, t);
|
162
64
|
},
|
163
65
|
|
164
|
-
md5cycle = function(x, k) {
|
66
|
+
md5cycle = function (x, k) {
|
165
67
|
var a = x[0],
|
166
68
|
b = x[1],
|
167
69
|
c = x[2],
|
@@ -241,16 +143,42 @@
|
|
241
143
|
x[3] = add32(d, x[3]);
|
242
144
|
},
|
243
145
|
|
244
|
-
|
146
|
+
/* there needs to be support for Unicode here,
|
147
|
+
* unless we pretend that we can redefine the MD-5
|
148
|
+
* algorithm for multi-byte characters (perhaps
|
149
|
+
* by adding every four 16-bit characters and
|
150
|
+
* shortening the sum to 32 bits). Otherwise
|
151
|
+
* I suggest performing MD-5 as if every character
|
152
|
+
* was two bytes--e.g., 0040 0025 = @%--but then
|
153
|
+
* how will an ordinary MD-5 sum be matched?
|
154
|
+
* There is no way to standardize text to something
|
155
|
+
* like UTF-8 before transformation; speed cost is
|
156
|
+
* utterly prohibitive. The JavaScript standard
|
157
|
+
* itself needs to look at this: it should start
|
158
|
+
* providing access to strings as preformed UTF-8
|
159
|
+
* 8-bit unsigned value arrays.
|
160
|
+
*/
|
161
|
+
md5blk = function (s) {
|
245
162
|
var md5blks = [],
|
246
163
|
i; /* Andy King said do it this way. */
|
164
|
+
|
165
|
+
for (i = 0; i < 64; i += 4) {
|
166
|
+
md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
|
167
|
+
}
|
168
|
+
return md5blks;
|
169
|
+
},
|
170
|
+
|
171
|
+
md5blk_array = function (a) {
|
172
|
+
var md5blks = [],
|
173
|
+
i; /* Andy King said do it this way. */
|
174
|
+
|
247
175
|
for (i = 0; i < 64; i += 4) {
|
248
|
-
md5blks[i >> 2] =
|
176
|
+
md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
|
249
177
|
}
|
250
178
|
return md5blks;
|
251
179
|
},
|
252
180
|
|
253
|
-
md51 = function(s) {
|
181
|
+
md51 = function (s) {
|
254
182
|
var n = s.length,
|
255
183
|
state = [1732584193, -271733879, -1732584194, 271733878],
|
256
184
|
i,
|
@@ -261,25 +189,61 @@
|
|
261
189
|
hi;
|
262
190
|
|
263
191
|
for (i = 64; i <= n; i += 64) {
|
264
|
-
md5cycle(state, md5blk(s.
|
192
|
+
md5cycle(state, md5blk(s.substring(i - 64, i)));
|
193
|
+
}
|
194
|
+
s = s.substring(i - 64);
|
195
|
+
length = s.length;
|
196
|
+
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
197
|
+
for (i = 0; i < length; i += 1) {
|
198
|
+
tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
|
199
|
+
}
|
200
|
+
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
|
201
|
+
if (i > 55) {
|
202
|
+
md5cycle(state, tail);
|
203
|
+
for (i = 0; i < 16; i += 1) {
|
204
|
+
tail[i] = 0;
|
205
|
+
}
|
265
206
|
}
|
266
|
-
|
267
|
-
//
|
207
|
+
|
208
|
+
// Beware that the final length might not fit in 32 bits so we take care of that
|
209
|
+
tmp = n * 8;
|
210
|
+
tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
|
211
|
+
lo = parseInt(tmp[2], 16);
|
212
|
+
hi = parseInt(tmp[1], 16) || 0;
|
213
|
+
|
214
|
+
tail[14] = lo;
|
215
|
+
tail[15] = hi;
|
216
|
+
|
217
|
+
md5cycle(state, tail);
|
218
|
+
return state;
|
219
|
+
},
|
220
|
+
|
221
|
+
md51_array = function (a) {
|
222
|
+
var n = a.length,
|
223
|
+
state = [1732584193, -271733879, -1732584194, 271733878],
|
224
|
+
i,
|
225
|
+
length,
|
226
|
+
tail,
|
227
|
+
tmp,
|
228
|
+
lo,
|
229
|
+
hi;
|
230
|
+
|
231
|
+
for (i = 64; i <= n; i += 64) {
|
232
|
+
md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
|
233
|
+
}
|
234
|
+
|
268
235
|
// Not sure if it is a bug, however IE10 will always produce a sub array of length 1
|
269
236
|
// containing the last element of the parent array if the sub array specified starts
|
270
237
|
// beyond the length of the parent array - weird.
|
271
238
|
// https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
else
|
276
|
-
s = new Uint8Array(0);
|
277
|
-
|
278
|
-
length = s.length;
|
239
|
+
a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
|
240
|
+
|
241
|
+
length = a.length;
|
279
242
|
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
280
243
|
for (i = 0; i < length; i += 1) {
|
281
|
-
tail[i >> 2] |=
|
244
|
+
tail[i >> 2] |= a[i] << ((i % 4) << 3);
|
282
245
|
}
|
246
|
+
|
283
247
|
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
|
284
248
|
if (i > 55) {
|
285
249
|
md5cycle(state, tail);
|
@@ -298,12 +262,13 @@
|
|
298
262
|
tail[15] = hi;
|
299
263
|
|
300
264
|
md5cycle(state, tail);
|
265
|
+
|
301
266
|
return state;
|
302
267
|
},
|
303
268
|
|
304
269
|
hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'],
|
305
270
|
|
306
|
-
rhex = function(n) {
|
271
|
+
rhex = function (n) {
|
307
272
|
var s = '',
|
308
273
|
j;
|
309
274
|
for (j = 0; j < 4; j += 1) {
|
@@ -312,7 +277,7 @@
|
|
312
277
|
return s;
|
313
278
|
},
|
314
279
|
|
315
|
-
hex = function(x) {
|
280
|
+
hex = function (x) {
|
316
281
|
var i;
|
317
282
|
for (i = 0; i < x.length; i += 1) {
|
318
283
|
x[i] = rhex(x[i]);
|
@@ -320,10 +285,12 @@
|
|
320
285
|
return x.join('');
|
321
286
|
},
|
322
287
|
|
323
|
-
md5 = function(s) {
|
288
|
+
md5 = function (s) {
|
324
289
|
return hex(md51(s));
|
325
290
|
},
|
326
291
|
|
292
|
+
|
293
|
+
|
327
294
|
////////////////////////////////////////////////////////////////////////////
|
328
295
|
|
329
296
|
/**
|
@@ -335,21 +302,35 @@
|
|
335
302
|
SparkMD5 = function () {
|
336
303
|
// call reset to init the instance
|
337
304
|
this.reset();
|
338
|
-
};
|
339
|
-
|
305
|
+
};
|
306
|
+
|
307
|
+
|
308
|
+
// In some cases the fast add32 function cannot be used..
|
309
|
+
if (md5('hello') !== '5d41402abc4b2a76b9719d911017c592') {
|
310
|
+
add32 = function (x, y) {
|
311
|
+
var lsw = (x & 0xFFFF) + (y & 0xFFFF),
|
312
|
+
msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
313
|
+
return (msw << 16) | (lsw & 0xFFFF);
|
314
|
+
};
|
315
|
+
}
|
316
|
+
|
340
317
|
|
341
318
|
/**
|
342
319
|
* Appends a string.
|
343
|
-
*
|
320
|
+
* A conversion will be applied if an utf8 string is detected.
|
344
321
|
*
|
345
322
|
* @param {String} str The string to be appended
|
346
323
|
*
|
347
324
|
* @return {SparkMD5} The instance itself
|
348
325
|
*/
|
349
326
|
SparkMD5.prototype.append = function (str) {
|
327
|
+
// converts the string to utf8 bytes if necessary
|
328
|
+
if (/[\u0080-\uFFFF]/.test(str)) {
|
329
|
+
str = unescape(encodeURIComponent(str));
|
330
|
+
}
|
350
331
|
|
351
|
-
//
|
352
|
-
this.appendBinary(
|
332
|
+
// then append as binary
|
333
|
+
this.appendBinary(str);
|
353
334
|
|
354
335
|
return this;
|
355
336
|
};
|
@@ -357,26 +338,22 @@
|
|
357
338
|
/**
|
358
339
|
* Appends a binary string.
|
359
340
|
*
|
360
|
-
* @param {
|
341
|
+
* @param {String} contents The binary string to be appended
|
361
342
|
*
|
362
343
|
* @return {SparkMD5} The instance itself
|
363
344
|
*/
|
364
345
|
SparkMD5.prototype.appendBinary = function (contents) {
|
365
|
-
|
366
|
-
|
346
|
+
this._buff += contents;
|
347
|
+
this._length += contents.length;
|
348
|
+
|
349
|
+
var length = this._buff.length,
|
367
350
|
i;
|
368
|
-
|
369
|
-
this._length += contents.byteLength;
|
370
|
-
|
351
|
+
|
371
352
|
for (i = 64; i <= length; i += 64) {
|
372
|
-
md5cycle(this._state, md5blk(
|
353
|
+
md5cycle(this._state, md5blk(this._buff.substring(i - 64, i)));
|
373
354
|
}
|
374
355
|
|
375
|
-
|
376
|
-
if((i - 64) < length)
|
377
|
-
this._buff = buff.subarray(i - 64);
|
378
|
-
else
|
379
|
-
this._buff = new Uint8Array(0);
|
356
|
+
this._buff = this._buff.substr(i - 64);
|
380
357
|
|
381
358
|
return this;
|
382
359
|
};
|
@@ -393,16 +370,34 @@
|
|
393
370
|
SparkMD5.prototype.end = function (raw) {
|
394
371
|
var buff = this._buff,
|
395
372
|
length = buff.length,
|
396
|
-
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
397
373
|
i,
|
398
|
-
|
374
|
+
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
375
|
+
ret;
|
376
|
+
|
377
|
+
for (i = 0; i < length; i += 1) {
|
378
|
+
tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
|
379
|
+
}
|
380
|
+
|
381
|
+
this._finish(tail, length);
|
382
|
+
ret = !!raw ? this._state : hex(this._state);
|
383
|
+
|
384
|
+
this.reset();
|
385
|
+
|
386
|
+
return ret;
|
387
|
+
};
|
388
|
+
|
389
|
+
/**
|
390
|
+
* Finish the final calculation based on the tail.
|
391
|
+
*
|
392
|
+
* @param {Array} tail The tail (will be modified)
|
393
|
+
* @param {Number} length The length of the remaining buffer
|
394
|
+
*/
|
395
|
+
SparkMD5.prototype._finish = function (tail, length) {
|
396
|
+
var i = length,
|
399
397
|
tmp,
|
400
398
|
lo,
|
401
399
|
hi;
|
402
400
|
|
403
|
-
for (i = 0; i < length; i += 1) {
|
404
|
-
tail[i >> 2] |= buff[i] << ((i % 4) << 3);
|
405
|
-
}
|
406
401
|
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
|
407
402
|
if (i > 55) {
|
408
403
|
md5cycle(this._state, tail);
|
@@ -421,12 +416,6 @@
|
|
421
416
|
tail[14] = lo;
|
422
417
|
tail[15] = hi;
|
423
418
|
md5cycle(this._state, tail);
|
424
|
-
|
425
|
-
ret = !!raw ? this._state : hex(this._state);
|
426
|
-
|
427
|
-
this.reset();
|
428
|
-
|
429
|
-
return ret;
|
430
419
|
};
|
431
420
|
|
432
421
|
/**
|
@@ -435,7 +424,7 @@
|
|
435
424
|
* @return {SparkMD5} The instance itself
|
436
425
|
*/
|
437
426
|
SparkMD5.prototype.reset = function () {
|
438
|
-
this._buff =
|
427
|
+
this._buff = "";
|
439
428
|
this._length = 0;
|
440
429
|
this._state = [1732584193, -271733879, -1732584194, 271733878];
|
441
430
|
|
@@ -452,8 +441,10 @@
|
|
452
441
|
delete this._length;
|
453
442
|
};
|
454
443
|
|
444
|
+
|
455
445
|
/**
|
456
|
-
* Performs the md5 hash on a string
|
446
|
+
* Performs the md5 hash on a string.
|
447
|
+
* A conversion will be applied if utf8 string is detected.
|
457
448
|
*
|
458
449
|
* @param {String} str The string
|
459
450
|
* @param {Boolean} raw True to get the raw result, false to get the hex result
|
@@ -461,21 +452,145 @@
|
|
461
452
|
* @return {String|Array} The result
|
462
453
|
*/
|
463
454
|
SparkMD5.hash = function (str, raw) {
|
464
|
-
|
455
|
+
// converts the string to utf8 bytes if necessary
|
456
|
+
if (/[\u0080-\uFFFF]/.test(str)) {
|
457
|
+
str = unescape(encodeURIComponent(str));
|
458
|
+
}
|
459
|
+
|
460
|
+
var hash = md51(str);
|
465
461
|
|
466
462
|
return !!raw ? hash : hex(hash);
|
467
463
|
};
|
468
464
|
|
469
465
|
/**
|
470
|
-
* Performs the md5 hash on a
|
466
|
+
* Performs the md5 hash on a binary string.
|
471
467
|
*
|
472
|
-
* @param {
|
468
|
+
* @param {String} content The binary string
|
473
469
|
* @param {Boolean} raw True to get the raw result, false to get the hex result
|
474
470
|
*
|
475
471
|
* @return {String|Array} The result
|
476
472
|
*/
|
477
473
|
SparkMD5.hashBinary = function (content, raw) {
|
478
|
-
var hash = md51(
|
474
|
+
var hash = md51(content);
|
475
|
+
|
476
|
+
return !!raw ? hash : hex(hash);
|
477
|
+
};
|
478
|
+
|
479
|
+
/**
|
480
|
+
* SparkMD5 OOP implementation for array buffers.
|
481
|
+
*
|
482
|
+
* Use this class to perform an incremental md5 ONLY for array buffers.
|
483
|
+
*/
|
484
|
+
SparkMD5.ArrayBuffer = function () {
|
485
|
+
// call reset to init the instance
|
486
|
+
this.reset();
|
487
|
+
};
|
488
|
+
|
489
|
+
////////////////////////////////////////////////////////////////////////////
|
490
|
+
|
491
|
+
/**
|
492
|
+
* Appends an array buffer.
|
493
|
+
*
|
494
|
+
* @param {ArrayBuffer} arr The array to be appended
|
495
|
+
*
|
496
|
+
* @return {SparkMD5.ArrayBuffer} The instance itself
|
497
|
+
*/
|
498
|
+
SparkMD5.ArrayBuffer.prototype.append = function (arr) {
|
499
|
+
// TODO: we could avoid the concatenation here but the algorithm would be more complex
|
500
|
+
// if you find yourself needing extra performance, please make a PR.
|
501
|
+
var buff = this._concatArrayBuffer(this._buff, arr),
|
502
|
+
length = buff.length,
|
503
|
+
i;
|
504
|
+
|
505
|
+
this._length += arr.byteLength;
|
506
|
+
|
507
|
+
for (i = 64; i <= length; i += 64) {
|
508
|
+
md5cycle(this._state, md5blk_array(buff.subarray(i - 64, i)));
|
509
|
+
}
|
510
|
+
|
511
|
+
// Avoids IE10 weirdness (documented above)
|
512
|
+
this._buff = (i - 64) < length ? buff.subarray(i - 64) : new Uint8Array(0);
|
513
|
+
|
514
|
+
return this;
|
515
|
+
};
|
516
|
+
|
517
|
+
/**
|
518
|
+
* Finishes the incremental computation, reseting the internal state and
|
519
|
+
* returning the result.
|
520
|
+
* Use the raw parameter to obtain the raw result instead of the hex one.
|
521
|
+
*
|
522
|
+
* @param {Boolean} raw True to get the raw result, false to get the hex result
|
523
|
+
*
|
524
|
+
* @return {String|Array} The result
|
525
|
+
*/
|
526
|
+
SparkMD5.ArrayBuffer.prototype.end = function (raw) {
|
527
|
+
var buff = this._buff,
|
528
|
+
length = buff.length,
|
529
|
+
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
530
|
+
i,
|
531
|
+
ret;
|
532
|
+
|
533
|
+
for (i = 0; i < length; i += 1) {
|
534
|
+
tail[i >> 2] |= buff[i] << ((i % 4) << 3);
|
535
|
+
}
|
536
|
+
|
537
|
+
this._finish(tail, length);
|
538
|
+
ret = !!raw ? this._state : hex(this._state);
|
539
|
+
|
540
|
+
this.reset();
|
541
|
+
|
542
|
+
return ret;
|
543
|
+
};
|
544
|
+
|
545
|
+
SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
|
546
|
+
|
547
|
+
/**
|
548
|
+
* Resets the internal state of the computation.
|
549
|
+
*
|
550
|
+
* @return {SparkMD5.ArrayBuffer} The instance itself
|
551
|
+
*/
|
552
|
+
SparkMD5.ArrayBuffer.prototype.reset = function () {
|
553
|
+
this._buff = new Uint8Array(0);
|
554
|
+
this._length = 0;
|
555
|
+
this._state = [1732584193, -271733879, -1732584194, 271733878];
|
556
|
+
|
557
|
+
return this;
|
558
|
+
};
|
559
|
+
|
560
|
+
/**
|
561
|
+
* Releases memory used by the incremental buffer and other aditional
|
562
|
+
* resources. If you plan to use the instance again, use reset instead.
|
563
|
+
*/
|
564
|
+
SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
|
565
|
+
|
566
|
+
/**
|
567
|
+
* Concats two array buffers, returning a new one.
|
568
|
+
*
|
569
|
+
* @param {ArrayBuffer} first The first array buffer
|
570
|
+
* @param {ArrayBuffer} second The second array buffer
|
571
|
+
*
|
572
|
+
* @return {ArrayBuffer} The new array buffer
|
573
|
+
*/
|
574
|
+
SparkMD5.ArrayBuffer.prototype._concatArrayBuffer = function (first, second) {
|
575
|
+
var firstLength = first.length,
|
576
|
+
result = new Uint8Array(firstLength + second.byteLength);
|
577
|
+
|
578
|
+
result.set(first);
|
579
|
+
result.set(new Uint8Array(second), firstLength);
|
580
|
+
|
581
|
+
return result;
|
582
|
+
};
|
583
|
+
|
584
|
+
/**
|
585
|
+
* Performs the md5 hash on an array buffer.
|
586
|
+
*
|
587
|
+
* @param {ArrayBuffer} arr The array buffer
|
588
|
+
* @param {Boolean} raw True to get the raw result, false to get the hex result
|
589
|
+
*
|
590
|
+
* @return {String|Array} The result
|
591
|
+
*/
|
592
|
+
SparkMD5.ArrayBuffer.hash = function (arr, raw) {
|
593
|
+
var hash = md51_array(new Uint8Array(arr));
|
479
594
|
|
480
595
|
return !!raw ? hash : hex(hash);
|
481
596
|
};
|