Commit | Line | Data |
---|---|---|
da6dad24 RK |
1 | (function(e){if("function"==typeof bootstrap)bootstrap("osmauth",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeOsmAuth=e}else"undefined"!=typeof window?window.osmAuth=e():global.osmAuth=e()})(function(){var define,ses,bootstrap,module,exports; |
2 | return (function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){ | |
3 | 'use strict'; | |
4 | ||
5 | var ohauth = require('ohauth'), | |
6 | xtend = require('xtend'), | |
7 | store = require('store'); | |
8 | ||
9 | // # osm-auth | |
10 | // | |
11 | // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo) | |
12 | // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing), | |
13 | // does not support custom headers, which this uses everywhere. | |
14 | module.exports = function(o) { | |
15 | ||
16 | var oauth = {}; | |
17 | ||
18 | // authenticated users will also have a request token secret, but it's | |
19 | // not used in transactions with the server | |
20 | oauth.authenticated = function() { | |
21 | return !!(token('oauth_token') && token('oauth_token_secret')); | |
22 | }; | |
23 | ||
24 | oauth.logout = function() { | |
25 | token('oauth_token', ''); | |
26 | token('oauth_token_secret', ''); | |
27 | token('oauth_request_token_secret', ''); | |
28 | return oauth; | |
29 | }; | |
30 | ||
31 | // TODO: detect lack of click event | |
32 | oauth.authenticate = function(callback) { | |
33 | if (oauth.authenticated()) return callback(); | |
34 | ||
35 | oauth.logout(); | |
36 | ||
37 | // ## Getting a request token | |
38 | var params = timenonce(getAuth(o)), | |
39 | url = o.url + '/oauth/request_token'; | |
40 | ||
41 | params.oauth_signature = ohauth.signature( | |
42 | o.oauth_secret, '', | |
43 | ohauth.baseString('POST', url, params)); | |
44 | ||
45 | if (!o.singlepage) { | |
46 | // Create a 600x550 popup window in the center of the screen | |
47 | var w = 600, h = 550, | |
48 | settings = [ | |
49 | ['width', w], ['height', h], | |
50 | ['left', screen.width / 2 - w / 2], | |
51 | ['top', screen.height / 2 - h / 2]].map(function(x) { | |
52 | return x.join('='); | |
53 | }).join(','), | |
54 | popup = window.open('about:blank', 'oauth_window', settings); | |
55 | } | |
56 | ||
57 | // Request a request token. When this is complete, the popup | |
58 | // window is redirected to OSM's authorization page. | |
59 | ohauth.xhr('POST', url, params, null, {}, reqTokenDone); | |
60 | o.loading(); | |
61 | ||
62 | function reqTokenDone(err, xhr) { | |
63 | o.done(); | |
64 | if (err) return callback(err); | |
65 | var resp = ohauth.stringQs(xhr.response); | |
66 | token('oauth_request_token_secret', resp.oauth_token_secret); | |
67 | var authorize_url = o.url + '/oauth/authorize?' + ohauth.qsString({ | |
68 | oauth_token: resp.oauth_token, | |
69 | oauth_callback: location.href.replace('index.html', '') | |
70 | .replace(/#.*/, '').replace(location.search, '') + o.landing | |
71 | }); | |
72 | ||
73 | if (o.singlepage) { | |
74 | location.href = authorize_url; | |
75 | } else { | |
76 | popup.location = authorize_url; | |
77 | } | |
78 | } | |
79 | ||
80 | // Called by a function in a landing page, in the popup window. The | |
81 | // window closes itself. | |
82 | window.authComplete = function(token) { | |
83 | var oauth_token = ohauth.stringQs(token.split('?')[1]); | |
84 | get_access_token(oauth_token.oauth_token); | |
85 | delete window.authComplete; | |
86 | }; | |
87 | ||
88 | // ## Getting an request token | |
89 | // | |
90 | // At this point we have an `oauth_token`, brought in from a function | |
91 | // call on a landing page popup. | |
92 | function get_access_token(oauth_token) { | |
93 | var url = o.url + '/oauth/access_token', | |
94 | params = timenonce(getAuth(o)), | |
95 | request_token_secret = token('oauth_request_token_secret'); | |
96 | params.oauth_token = oauth_token; | |
97 | params.oauth_signature = ohauth.signature( | |
98 | o.oauth_secret, | |
99 | request_token_secret, | |
100 | ohauth.baseString('POST', url, params)); | |
101 | ||
102 | // ## Getting an access token | |
103 | // | |
104 | // The final token required for authentication. At this point | |
105 | // we have a `request token secret` | |
106 | ohauth.xhr('POST', url, params, null, {}, accessTokenDone); | |
107 | o.loading(); | |
108 | } | |
109 | ||
110 | function accessTokenDone(err, xhr) { | |
111 | o.done(); | |
112 | if (err) return callback(err); | |
113 | var access_token = ohauth.stringQs(xhr.response); | |
114 | token('oauth_token', access_token.oauth_token); | |
115 | token('oauth_token_secret', access_token.oauth_token_secret); | |
116 | callback(null, oauth); | |
117 | } | |
118 | }; | |
119 | ||
120 | oauth.bootstrapToken = function(oauth_token, callback) { | |
121 | // ## Getting an request token | |
122 | // At this point we have an `oauth_token`, brought in from a function | |
123 | // call on a landing page popup. | |
124 | function get_access_token(oauth_token) { | |
125 | var url = o.url + '/oauth/access_token', | |
126 | params = timenonce(getAuth(o)), | |
127 | request_token_secret = token('oauth_request_token_secret'); | |
128 | params.oauth_token = oauth_token; | |
129 | params.oauth_signature = ohauth.signature( | |
130 | o.oauth_secret, | |
131 | request_token_secret, | |
132 | ohauth.baseString('POST', url, params)); | |
133 | ||
134 | // ## Getting an access token | |
135 | // The final token required for authentication. At this point | |
136 | // we have a `request token secret` | |
137 | ohauth.xhr('POST', url, params, null, {}, accessTokenDone); | |
138 | o.loading(); | |
139 | } | |
140 | ||
141 | function accessTokenDone(err, xhr) { | |
142 | o.done(); | |
143 | if (err) return callback(err); | |
144 | var access_token = ohauth.stringQs(xhr.response); | |
145 | token('oauth_token', access_token.oauth_token); | |
146 | token('oauth_token_secret', access_token.oauth_token_secret); | |
147 | callback(null, oauth); | |
148 | } | |
149 | ||
150 | get_access_token(oauth_token); | |
151 | }; | |
152 | ||
153 | // # xhr | |
154 | // | |
155 | // A single XMLHttpRequest wrapper that does authenticated calls if the | |
156 | // user has logged in. | |
157 | oauth.xhr = function(options, callback) { | |
158 | if (!oauth.authenticated()) { | |
159 | if (o.auto) return oauth.authenticate(run); | |
160 | else return callback('not authenticated', null); | |
161 | } else return run(); | |
162 | ||
163 | function run() { | |
164 | var params = timenonce(getAuth(o)), | |
165 | url = o.url + options.path, | |
166 | oauth_token_secret = token('oauth_token_secret'); | |
167 | ||
168 | // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1 | |
169 | if ((!options.options || !options.options.header || | |
170 | options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') && | |
171 | options.content) { | |
172 | params = xtend(params, ohauth.stringQs(options.content)); | |
173 | } | |
174 | ||
175 | params.oauth_token = token('oauth_token'); | |
176 | params.oauth_signature = ohauth.signature( | |
177 | o.oauth_secret, | |
178 | oauth_token_secret, | |
179 | ohauth.baseString(options.method, url, params)); | |
180 | ||
181 | ohauth.xhr(options.method, | |
182 | url, params, options.content, options.options, done); | |
183 | } | |
184 | ||
185 | function done(err, xhr) { | |
186 | if (err) return callback(err); | |
187 | else if (xhr.responseXML) return callback(err, xhr.responseXML); | |
188 | else return callback(err, xhr.response); | |
189 | } | |
190 | }; | |
191 | ||
192 | // pre-authorize this object, if we can just get a token and token_secret | |
193 | // from the start | |
194 | oauth.preauth = function(c) { | |
195 | if (!c) return; | |
196 | if (c.oauth_token) token('oauth_token', c.oauth_token); | |
197 | if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret); | |
198 | return oauth; | |
199 | }; | |
200 | ||
201 | oauth.options = function(_) { | |
202 | if (!arguments.length) return o; | |
203 | ||
204 | o = _; | |
205 | ||
206 | o.url = o.url || 'http://www.openstreetmap.org'; | |
207 | o.landing = o.landing || 'land.html'; | |
208 | ||
209 | o.singlepage = o.singlepage || false; | |
210 | ||
211 | // Optional loading and loading-done functions for nice UI feedback. | |
212 | // by default, no-ops | |
213 | o.loading = o.loading || function() {}; | |
214 | o.done = o.done || function() {}; | |
215 | ||
216 | return oauth.preauth(o); | |
217 | }; | |
218 | ||
219 | // 'stamp' an authentication object from `getAuth()` | |
220 | // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce) | |
221 | // and timestamp | |
222 | function timenonce(o) { | |
223 | o.oauth_timestamp = ohauth.timestamp(); | |
224 | o.oauth_nonce = ohauth.nonce(); | |
225 | return o; | |
226 | } | |
227 | ||
228 | // get/set tokens. These are prefixed with the base URL so that `osm-auth` | |
229 | // can be used with multiple APIs and the keys in `localStorage` | |
230 | // will not clash | |
231 | var token; | |
232 | ||
233 | if (store.enabled) { | |
234 | token = function (x, y) { | |
235 | if (arguments.length === 1) return store.get(o.url + x); | |
236 | else if (arguments.length === 2) return store.set(o.url + x, y); | |
237 | }; | |
238 | } else { | |
239 | var storage = {}; | |
240 | token = function (x, y) { | |
241 | if (arguments.length === 1) return storage[o.url + x]; | |
242 | else if (arguments.length === 2) return storage[o.url + x] = y; | |
243 | }; | |
244 | } | |
245 | ||
246 | // Get an authentication object. If you just add and remove properties | |
247 | // from a single object, you'll need to use `delete` to make sure that | |
248 | // it doesn't contain undesired properties for authentication | |
249 | function getAuth(o) { | |
250 | return { | |
251 | oauth_consumer_key: o.oauth_consumer_key, | |
252 | oauth_signature_method: "HMAC-SHA1" | |
253 | }; | |
254 | } | |
255 | ||
256 | // potentially pre-authorize | |
257 | oauth.options(o); | |
258 | ||
259 | return oauth; | |
260 | }; | |
261 | ||
262 | },{"ohauth":2,"xtend":3,"store":4}],4:[function(require,module,exports){ | |
263 | ;(function(win){ | |
264 | var store = {}, | |
265 | doc = win.document, | |
266 | localStorageName = 'localStorage', | |
267 | scriptTag = 'script', | |
268 | storage | |
269 | ||
270 | store.disabled = false | |
271 | store.set = function(key, value) {} | |
272 | store.get = function(key) {} | |
273 | store.remove = function(key) {} | |
274 | store.clear = function() {} | |
275 | store.transact = function(key, defaultVal, transactionFn) { | |
276 | var val = store.get(key) | |
277 | if (transactionFn == null) { | |
278 | transactionFn = defaultVal | |
279 | defaultVal = null | |
280 | } | |
281 | if (typeof val == 'undefined') { val = defaultVal || {} } | |
282 | transactionFn(val) | |
283 | store.set(key, val) | |
284 | } | |
285 | store.getAll = function() {} | |
286 | store.forEach = function() {} | |
287 | ||
288 | store.serialize = function(value) { | |
289 | return JSON.stringify(value) | |
290 | } | |
291 | store.deserialize = function(value) { | |
292 | if (typeof value != 'string') { return undefined } | |
293 | try { return JSON.parse(value) } | |
294 | catch(e) { return value || undefined } | |
295 | } | |
296 | ||
297 | // Functions to encapsulate questionable FireFox 3.6.13 behavior | |
298 | // when about.config::dom.storage.enabled === false | |
299 | // See https://github.com/marcuswestin/store.js/issues#issue/13 | |
300 | function isLocalStorageNameSupported() { | |
301 | try { return (localStorageName in win && win[localStorageName]) } | |
302 | catch(err) { return false } | |
303 | } | |
304 | ||
305 | if (isLocalStorageNameSupported()) { | |
306 | storage = win[localStorageName] | |
307 | store.set = function(key, val) { | |
308 | if (val === undefined) { return store.remove(key) } | |
309 | storage.setItem(key, store.serialize(val)) | |
310 | return val | |
311 | } | |
312 | store.get = function(key) { return store.deserialize(storage.getItem(key)) } | |
313 | store.remove = function(key) { storage.removeItem(key) } | |
314 | store.clear = function() { storage.clear() } | |
315 | store.getAll = function() { | |
316 | var ret = {} | |
317 | store.forEach(function(key, val) { | |
318 | ret[key] = val | |
319 | }) | |
320 | return ret | |
321 | } | |
322 | store.forEach = function(callback) { | |
323 | for (var i=0; i<storage.length; i++) { | |
324 | var key = storage.key(i) | |
325 | callback(key, store.get(key)) | |
326 | } | |
327 | } | |
328 | } else if (doc.documentElement.addBehavior) { | |
329 | var storageOwner, | |
330 | storageContainer | |
331 | // Since #userData storage applies only to specific paths, we need to | |
332 | // somehow link our data to a specific path. We choose /favicon.ico | |
333 | // as a pretty safe option, since all browsers already make a request to | |
334 | // this URL anyway and being a 404 will not hurt us here. We wrap an | |
335 | // iframe pointing to the favicon in an ActiveXObject(htmlfile) object | |
336 | // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx) | |
337 | // since the iframe access rules appear to allow direct access and | |
338 | // manipulation of the document element, even for a 404 page. This | |
339 | // document can be used instead of the current document (which would | |
340 | // have been limited to the current path) to perform #userData storage. | |
341 | try { | |
342 | storageContainer = new ActiveXObject('htmlfile') | |
343 | storageContainer.open() | |
344 | storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>') | |
345 | storageContainer.close() | |
346 | storageOwner = storageContainer.w.frames[0].document | |
347 | storage = storageOwner.createElement('div') | |
348 | } catch(e) { | |
349 | // somehow ActiveXObject instantiation failed (perhaps some special | |
350 | // security settings or otherwse), fall back to per-path storage | |
351 | storage = doc.createElement('div') | |
352 | storageOwner = doc.body | |
353 | } | |
354 | function withIEStorage(storeFunction) { | |
355 | return function() { | |
356 | var args = Array.prototype.slice.call(arguments, 0) | |
357 | args.unshift(storage) | |
358 | // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx | |
359 | // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx | |
360 | storageOwner.appendChild(storage) | |
361 | storage.addBehavior('#default#userData') | |
362 | storage.load(localStorageName) | |
363 | var result = storeFunction.apply(store, args) | |
364 | storageOwner.removeChild(storage) | |
365 | return result | |
366 | } | |
367 | } | |
368 | ||
369 | // In IE7, keys cannot start with a digit or contain certain chars. | |
370 | // See https://github.com/marcuswestin/store.js/issues/40 | |
371 | // See https://github.com/marcuswestin/store.js/issues/83 | |
372 | var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g") | |
373 | function ieKeyFix(key) { | |
374 | return key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___') | |
375 | } | |
376 | store.set = withIEStorage(function(storage, key, val) { | |
377 | key = ieKeyFix(key) | |
378 | if (val === undefined) { return store.remove(key) } | |
379 | storage.setAttribute(key, store.serialize(val)) | |
380 | storage.save(localStorageName) | |
381 | return val | |
382 | }) | |
383 | store.get = withIEStorage(function(storage, key) { | |
384 | key = ieKeyFix(key) | |
385 | return store.deserialize(storage.getAttribute(key)) | |
386 | }) | |
387 | store.remove = withIEStorage(function(storage, key) { | |
388 | key = ieKeyFix(key) | |
389 | storage.removeAttribute(key) | |
390 | storage.save(localStorageName) | |
391 | }) | |
392 | store.clear = withIEStorage(function(storage) { | |
393 | var attributes = storage.XMLDocument.documentElement.attributes | |
394 | storage.load(localStorageName) | |
395 | for (var i=0, attr; attr=attributes[i]; i++) { | |
396 | storage.removeAttribute(attr.name) | |
397 | } | |
398 | storage.save(localStorageName) | |
399 | }) | |
400 | store.getAll = function(storage) { | |
401 | var ret = {} | |
402 | store.forEach(function(key, val) { | |
403 | ret[key] = val | |
404 | }) | |
405 | return ret | |
406 | } | |
407 | store.forEach = withIEStorage(function(storage, callback) { | |
408 | var attributes = storage.XMLDocument.documentElement.attributes | |
409 | for (var i=0, attr; attr=attributes[i]; ++i) { | |
410 | callback(attr.name, store.deserialize(storage.getAttribute(attr.name))) | |
411 | } | |
412 | }) | |
413 | } | |
414 | ||
415 | try { | |
416 | var testKey = '__storejs__' | |
417 | store.set(testKey, testKey) | |
418 | if (store.get(testKey) != testKey) { store.disabled = true } | |
419 | store.remove(testKey) | |
420 | } catch(e) { | |
421 | store.disabled = true | |
422 | } | |
423 | store.enabled = !store.disabled | |
424 | ||
425 | if (typeof module != 'undefined' && module.exports && this.module !== module) { module.exports = store } | |
426 | else if (typeof define === 'function' && define.amd) { define(store) } | |
427 | else { win.store = store } | |
428 | ||
429 | })(Function('return this')()); | |
430 | ||
431 | },{}],5:[function(require,module,exports){ | |
432 | module.exports = hasKeys | |
433 | ||
434 | function hasKeys(source) { | |
435 | return source !== null && | |
436 | (typeof source === "object" || | |
437 | typeof source === "function") | |
438 | } | |
439 | ||
440 | },{}],3:[function(require,module,exports){ | |
441 | var Keys = require("object-keys") | |
442 | var hasKeys = require("./has-keys") | |
443 | ||
444 | module.exports = extend | |
445 | ||
446 | function extend() { | |
447 | var target = {} | |
448 | ||
449 | for (var i = 0; i < arguments.length; i++) { | |
450 | var source = arguments[i] | |
451 | ||
452 | if (!hasKeys(source)) { | |
453 | continue | |
454 | } | |
455 | ||
456 | var keys = Keys(source) | |
457 | ||
458 | for (var j = 0; j < keys.length; j++) { | |
459 | var name = keys[j] | |
460 | target[name] = source[name] | |
461 | } | |
462 | } | |
463 | ||
464 | return target | |
465 | } | |
466 | ||
467 | },{"./has-keys":5,"object-keys":6}],7:[function(require,module,exports){ | |
468 | (function(global){/** | |
469 | * jshashes - https://github.com/h2non/jshashes | |
470 | * Released under the "New BSD" license | |
471 | * | |
472 | * Algorithms specification: | |
473 | * | |
474 | * MD5 - http://www.ietf.org/rfc/rfc1321.txt | |
475 | * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html | |
476 | * SHA1 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf | |
477 | * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf | |
478 | * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf | |
479 | * HMAC - http://www.ietf.org/rfc/rfc2104.txt | |
480 | */ | |
481 | (function() { | |
482 | var Hashes; | |
483 | ||
484 | function utf8Encode(str) { | |
485 | var x, y, output = '', | |
486 | i = -1, | |
487 | l; | |
488 | ||
489 | if (str && str.length) { | |
490 | l = str.length; | |
491 | while ((i += 1) < l) { | |
492 | /* Decode utf-16 surrogate pairs */ | |
493 | x = str.charCodeAt(i); | |
494 | y = i + 1 < l ? str.charCodeAt(i + 1) : 0; | |
495 | if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) { | |
496 | x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); | |
497 | i += 1; | |
498 | } | |
499 | /* Encode output as utf-8 */ | |
500 | if (x <= 0x7F) { | |
501 | output += String.fromCharCode(x); | |
502 | } else if (x <= 0x7FF) { | |
503 | output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), | |
504 | 0x80 | (x & 0x3F)); | |
505 | } else if (x <= 0xFFFF) { | |
506 | output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), | |
507 | 0x80 | ((x >>> 6) & 0x3F), | |
508 | 0x80 | (x & 0x3F)); | |
509 | } else if (x <= 0x1FFFFF) { | |
510 | output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), | |
511 | 0x80 | ((x >>> 12) & 0x3F), | |
512 | 0x80 | ((x >>> 6) & 0x3F), | |
513 | 0x80 | (x & 0x3F)); | |
514 | } | |
515 | } | |
516 | } | |
517 | return output; | |
518 | } | |
519 | ||
520 | function utf8Decode(str) { | |
521 | var i, ac, c1, c2, c3, arr = [], | |
522 | l; | |
523 | i = ac = c1 = c2 = c3 = 0; | |
524 | ||
525 | if (str && str.length) { | |
526 | l = str.length; | |
527 | str += ''; | |
528 | ||
529 | while (i < l) { | |
530 | c1 = str.charCodeAt(i); | |
531 | ac += 1; | |
532 | if (c1 < 128) { | |
533 | arr[ac] = String.fromCharCode(c1); | |
534 | i += 1; | |
535 | } else if (c1 > 191 && c1 < 224) { | |
536 | c2 = str.charCodeAt(i + 1); | |
537 | arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); | |
538 | i += 2; | |
539 | } else { | |
540 | c2 = str.charCodeAt(i + 1); | |
541 | c3 = str.charCodeAt(i + 2); | |
542 | arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); | |
543 | i += 3; | |
544 | } | |
545 | } | |
546 | } | |
547 | return arr.join(''); | |
548 | } | |
549 | ||
550 | /** | |
551 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally | |
552 | * to work around bugs in some JS interpreters. | |
553 | */ | |
554 | ||
555 | function safe_add(x, y) { | |
556 | var lsw = (x & 0xFFFF) + (y & 0xFFFF), | |
557 | msw = (x >> 16) + (y >> 16) + (lsw >> 16); | |
558 | return (msw << 16) | (lsw & 0xFFFF); | |
559 | } | |
560 | ||
561 | /** | |
562 | * Bitwise rotate a 32-bit number to the left. | |
563 | */ | |
564 | ||
565 | function bit_rol(num, cnt) { | |
566 | return (num << cnt) | (num >>> (32 - cnt)); | |
567 | } | |
568 | ||
569 | /** | |
570 | * Convert a raw string to a hex string | |
571 | */ | |
572 | ||
573 | function rstr2hex(input, hexcase) { | |
574 | var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef', | |
575 | output = '', | |
576 | x, i = 0, | |
577 | l = input.length; | |
578 | for (; i < l; i += 1) { | |
579 | x = input.charCodeAt(i); | |
580 | output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F); | |
581 | } | |
582 | return output; | |
583 | } | |
584 | ||
585 | /** | |
586 | * Encode a string as utf-16 | |
587 | */ | |
588 | ||
589 | function str2rstr_utf16le(input) { | |
590 | var i, l = input.length, | |
591 | output = ''; | |
592 | for (i = 0; i < l; i += 1) { | |
593 | output += String.fromCharCode(input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF); | |
594 | } | |
595 | return output; | |
596 | } | |
597 | ||
598 | function str2rstr_utf16be(input) { | |
599 | var i, l = input.length, | |
600 | output = ''; | |
601 | for (i = 0; i < l; i += 1) { | |
602 | output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF); | |
603 | } | |
604 | return output; | |
605 | } | |
606 | ||
607 | /** | |
608 | * Convert an array of big-endian words to a string | |
609 | */ | |
610 | ||
611 | function binb2rstr(input) { | |
612 | var i, l = input.length * 32, | |
613 | output = ''; | |
614 | for (i = 0; i < l; i += 8) { | |
615 | output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF); | |
616 | } | |
617 | return output; | |
618 | } | |
619 | ||
620 | /** | |
621 | * Convert an array of little-endian words to a string | |
622 | */ | |
623 | ||
624 | function binl2rstr(input) { | |
625 | var i, l = input.length * 32, | |
626 | output = ''; | |
627 | for (i = 0; i < l; i += 8) { | |
628 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); | |
629 | } | |
630 | return output; | |
631 | } | |
632 | ||
633 | /** | |
634 | * Convert a raw string to an array of little-endian words | |
635 | * Characters >255 have their high-byte silently ignored. | |
636 | */ | |
637 | ||
638 | function rstr2binl(input) { | |
639 | var i, l = input.length * 8, | |
640 | output = Array(input.length >> 2), | |
641 | lo = output.length; | |
642 | for (i = 0; i < lo; i += 1) { | |
643 | output[i] = 0; | |
644 | } | |
645 | for (i = 0; i < l; i += 8) { | |
646 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); | |
647 | } | |
648 | return output; | |
649 | } | |
650 | ||
651 | /** | |
652 | * Convert a raw string to an array of big-endian words | |
653 | * Characters >255 have their high-byte silently ignored. | |
654 | */ | |
655 | ||
656 | function rstr2binb(input) { | |
657 | var i, l = input.length * 8, | |
658 | output = Array(input.length >> 2), | |
659 | lo = output.length; | |
660 | for (i = 0; i < lo; i += 1) { | |
661 | output[i] = 0; | |
662 | } | |
663 | for (i = 0; i < l; i += 8) { | |
664 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); | |
665 | } | |
666 | return output; | |
667 | } | |
668 | ||
669 | /** | |
670 | * Convert a raw string to an arbitrary string encoding | |
671 | */ | |
672 | ||
673 | function rstr2any(input, encoding) { | |
674 | var divisor = encoding.length, | |
675 | remainders = Array(), | |
676 | i, q, x, ld, quotient, dividend, output, full_length; | |
677 | ||
678 | /* Convert to an array of 16-bit big-endian values, forming the dividend */ | |
679 | dividend = Array(Math.ceil(input.length / 2)); | |
680 | ld = dividend.length; | |
681 | for (i = 0; i < ld; i += 1) { | |
682 | dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); | |
683 | } | |
684 | ||
685 | /** | |
686 | * Repeatedly perform a long division. The binary array forms the dividend, | |
687 | * the length of the encoding is the divisor. Once computed, the quotient | |
688 | * forms the dividend for the next step. We stop when the dividend is zerHashes. | |
689 | * All remainders are stored for later use. | |
690 | */ | |
691 | while (dividend.length > 0) { | |
692 | quotient = Array(); | |
693 | x = 0; | |
694 | for (i = 0; i < dividend.length; i += 1) { | |
695 | x = (x << 16) + dividend[i]; | |
696 | q = Math.floor(x / divisor); | |
697 | x -= q * divisor; | |
698 | if (quotient.length > 0 || q > 0) { | |
699 | quotient[quotient.length] = q; | |
700 | } | |
701 | } | |
702 | remainders[remainders.length] = x; | |
703 | dividend = quotient; | |
704 | } | |
705 | ||
706 | /* Convert the remainders to the output string */ | |
707 | output = ''; | |
708 | for (i = remainders.length - 1; i >= 0; i--) { | |
709 | output += encoding.charAt(remainders[i]); | |
710 | } | |
711 | ||
712 | /* Append leading zero equivalents */ | |
713 | full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))); | |
714 | for (i = output.length; i < full_length; i += 1) { | |
715 | output = encoding[0] + output; | |
716 | } | |
717 | return output; | |
718 | } | |
719 | ||
720 | /** | |
721 | * Convert a raw string to a base-64 string | |
722 | */ | |
723 | ||
724 | function rstr2b64(input, b64pad) { | |
725 | var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', | |
726 | output = '', | |
727 | len = input.length, | |
728 | i, j, triplet; | |
729 | b64pad = b64pad || '='; | |
730 | for (i = 0; i < len; i += 3) { | |
731 | triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0); | |
732 | for (j = 0; j < 4; j += 1) { | |
733 | if (i * 8 + j * 6 > input.length * 8) { | |
734 | output += b64pad; | |
735 | } else { | |
736 | output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F); | |
737 | } | |
738 | } | |
739 | } | |
740 | return output; | |
741 | } | |
742 | ||
743 | Hashes = { | |
744 | /** | |
745 | * @property {String} version | |
746 | * @readonly | |
747 | */ | |
748 | VERSION: '1.0.5', | |
749 | /** | |
750 | * @member Hashes | |
751 | * @class Base64 | |
752 | * @constructor | |
753 | */ | |
754 | Base64: function() { | |
755 | // private properties | |
756 | var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', | |
757 | pad = '=', // default pad according with the RFC standard | |
758 | url = false, // URL encoding support @todo | |
759 | utf8 = true; // by default enable UTF-8 support encoding | |
760 | ||
761 | // public method for encoding | |
762 | this.encode = function(input) { | |
763 | var i, j, triplet, | |
764 | output = '', | |
765 | len = input.length; | |
766 | ||
767 | pad = pad || '='; | |
768 | input = (utf8) ? utf8Encode(input) : input; | |
769 | ||
770 | for (i = 0; i < len; i += 3) { | |
771 | triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0); | |
772 | for (j = 0; j < 4; j += 1) { | |
773 | if (i * 8 + j * 6 > len * 8) { | |
774 | output += pad; | |
775 | } else { | |
776 | output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F); | |
777 | } | |
778 | } | |
779 | } | |
780 | return output; | |
781 | }; | |
782 | ||
783 | // public method for decoding | |
784 | this.decode = function(input) { | |
785 | // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; | |
786 | var i, o1, o2, o3, h1, h2, h3, h4, bits, ac, | |
787 | dec = '', | |
788 | arr = []; | |
789 | if (!input) { | |
790 | return input; | |
791 | } | |
792 | ||
793 | i = ac = 0; | |
794 | input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '=' | |
795 | //input += ''; | |
796 | ||
797 | do { // unpack four hexets into three octets using index points in b64 | |
798 | h1 = tab.indexOf(input.charAt(i += 1)); | |
799 | h2 = tab.indexOf(input.charAt(i += 1)); | |
800 | h3 = tab.indexOf(input.charAt(i += 1)); | |
801 | h4 = tab.indexOf(input.charAt(i += 1)); | |
802 | ||
803 | bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; | |
804 | ||
805 | o1 = bits >> 16 & 0xff; | |
806 | o2 = bits >> 8 & 0xff; | |
807 | o3 = bits & 0xff; | |
808 | ac += 1; | |
809 | ||
810 | if (h3 === 64) { | |
811 | arr[ac] = String.fromCharCode(o1); | |
812 | } else if (h4 === 64) { | |
813 | arr[ac] = String.fromCharCode(o1, o2); | |
814 | } else { | |
815 | arr[ac] = String.fromCharCode(o1, o2, o3); | |
816 | } | |
817 | } while (i < input.length); | |
818 | ||
819 | dec = arr.join(''); | |
820 | dec = (utf8) ? utf8Decode(dec) : dec; | |
821 | ||
822 | return dec; | |
823 | }; | |
824 | ||
825 | // set custom pad string | |
826 | this.setPad = function(str) { | |
827 | pad = str || pad; | |
828 | return this; | |
829 | }; | |
830 | // set custom tab string characters | |
831 | this.setTab = function(str) { | |
832 | tab = str || tab; | |
833 | return this; | |
834 | }; | |
835 | this.setUTF8 = function(bool) { | |
836 | if (typeof bool === 'boolean') { | |
837 | utf8 = bool; | |
838 | } | |
839 | return this; | |
840 | }; | |
841 | }, | |
842 | ||
843 | /** | |
844 | * CRC-32 calculation | |
845 | * @member Hashes | |
846 | * @method CRC32 | |
847 | * @static | |
848 | * @param {String} str Input String | |
849 | * @return {String} | |
850 | */ | |
851 | CRC32: function(str) { | |
852 | var crc = 0, | |
853 | x = 0, | |
854 | y = 0, | |
855 | table, i, iTop; | |
856 | str = utf8Encode(str); | |
857 | ||
858 | table = [ | |
859 | '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ', | |
860 | '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ', | |
861 | '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ', | |
862 | '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ', | |
863 | 'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ', | |
864 | '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ', | |
865 | 'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ', | |
866 | '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ', | |
867 | 'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ', | |
868 | '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ', | |
869 | 'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ', | |
870 | '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ', | |
871 | 'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ', | |
872 | '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ', | |
873 | '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ', | |
874 | '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ', | |
875 | '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ', | |
876 | 'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ', | |
877 | '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ', | |
878 | 'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ', | |
879 | '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ', | |
880 | 'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ', | |
881 | '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ', | |
882 | 'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ', | |
883 | '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ', | |
884 | 'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D' | |
885 | ].join(''); | |
886 | ||
887 | crc = crc ^ (-1); | |
888 | for (i = 0, iTop = str.length; i < iTop; i += 1) { | |
889 | y = (crc ^ str.charCodeAt(i)) & 0xFF; | |
890 | x = '0x' + table.substr(y * 9, 8); | |
891 | crc = (crc >>> 8) ^ x; | |
892 | } | |
893 | // always return a positive number (that's what >>> 0 does) | |
894 | return (crc ^ (-1)) >>> 0; | |
895 | }, | |
896 | /** | |
897 | * @member Hashes | |
898 | * @class MD5 | |
899 | * @constructor | |
900 | * @param {Object} [config] | |
901 | * | |
902 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message | |
903 | * Digest Algorithm, as defined in RFC 1321. | |
904 | * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 | |
905 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
906 | * See <http://pajhome.org.uk/crypt/md5> for more infHashes. | |
907 | */ | |
908 | MD5: function(options) { | |
909 | /** | |
910 | * Private config properties. You may need to tweak these to be compatible with | |
911 | * the server-side, but the defaults work in most cases. | |
912 | * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase} | |
913 | */ | |
914 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase | |
915 | b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance | |
916 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding | |
917 | ||
918 | // privileged (public) methods | |
919 | this.hex = function(s) { | |
920 | return rstr2hex(rstr(s, utf8), hexcase); | |
921 | }; | |
922 | this.b64 = function(s) { | |
923 | return rstr2b64(rstr(s), b64pad); | |
924 | }; | |
925 | this.any = function(s, e) { | |
926 | return rstr2any(rstr(s, utf8), e); | |
927 | }; | |
928 | this.raw = function(s) { | |
929 | return rstr(s, utf8); | |
930 | }; | |
931 | this.hex_hmac = function(k, d) { | |
932 | return rstr2hex(rstr_hmac(k, d), hexcase); | |
933 | }; | |
934 | this.b64_hmac = function(k, d) { | |
935 | return rstr2b64(rstr_hmac(k, d), b64pad); | |
936 | }; | |
937 | this.any_hmac = function(k, d, e) { | |
938 | return rstr2any(rstr_hmac(k, d), e); | |
939 | }; | |
940 | /** | |
941 | * Perform a simple self-test to see if the VM is working | |
942 | * @return {String} Hexadecimal hash sample | |
943 | */ | |
944 | this.vm_test = function() { | |
945 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; | |
946 | }; | |
947 | /** | |
948 | * Enable/disable uppercase hexadecimal returned string | |
949 | * @param {Boolean} | |
950 | * @return {Object} this | |
951 | */ | |
952 | this.setUpperCase = function(a) { | |
953 | if (typeof a === 'boolean') { | |
954 | hexcase = a; | |
955 | } | |
956 | return this; | |
957 | }; | |
958 | /** | |
959 | * Defines a base64 pad string | |
960 | * @param {String} Pad | |
961 | * @return {Object} this | |
962 | */ | |
963 | this.setPad = function(a) { | |
964 | b64pad = a || b64pad; | |
965 | return this; | |
966 | }; | |
967 | /** | |
968 | * Defines a base64 pad string | |
969 | * @param {Boolean} | |
970 | * @return {Object} [this] | |
971 | */ | |
972 | this.setUTF8 = function(a) { | |
973 | if (typeof a === 'boolean') { | |
974 | utf8 = a; | |
975 | } | |
976 | return this; | |
977 | }; | |
978 | ||
979 | // private methods | |
980 | ||
981 | /** | |
982 | * Calculate the MD5 of a raw string | |
983 | */ | |
984 | ||
985 | function rstr(s) { | |
986 | s = (utf8) ? utf8Encode(s) : s; | |
987 | return binl2rstr(binl(rstr2binl(s), s.length * 8)); | |
988 | } | |
989 | ||
990 | /** | |
991 | * Calculate the HMAC-MD5, of a key and some data (raw strings) | |
992 | */ | |
993 | ||
994 | function rstr_hmac(key, data) { | |
995 | var bkey, ipad, opad, hash, i; | |
996 | ||
997 | key = (utf8) ? utf8Encode(key) : key; | |
998 | data = (utf8) ? utf8Encode(data) : data; | |
999 | bkey = rstr2binl(key); | |
1000 | if (bkey.length > 16) { | |
1001 | bkey = binl(bkey, key.length * 8); | |
1002 | } | |
1003 | ||
1004 | ipad = Array(16), opad = Array(16); | |
1005 | for (i = 0; i < 16; i += 1) { | |
1006 | ipad[i] = bkey[i] ^ 0x36363636; | |
1007 | opad[i] = bkey[i] ^ 0x5C5C5C5C; | |
1008 | } | |
1009 | hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8); | |
1010 | return binl2rstr(binl(opad.concat(hash), 512 + 128)); | |
1011 | } | |
1012 | ||
1013 | /** | |
1014 | * Calculate the MD5 of an array of little-endian words, and a bit length. | |
1015 | */ | |
1016 | ||
1017 | function binl(x, len) { | |
1018 | var i, olda, oldb, oldc, oldd, | |
1019 | a = 1732584193, | |
1020 | b = -271733879, | |
1021 | c = -1732584194, | |
1022 | d = 271733878; | |
1023 | ||
1024 | /* append padding */ | |
1025 | x[len >> 5] |= 0x80 << ((len) % 32); | |
1026 | x[(((len + 64) >>> 9) << 4) + 14] = len; | |
1027 | ||
1028 | for (i = 0; i < x.length; i += 16) { | |
1029 | olda = a; | |
1030 | oldb = b; | |
1031 | oldc = c; | |
1032 | oldd = d; | |
1033 | ||
1034 | a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936); | |
1035 | d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); | |
1036 | c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); | |
1037 | b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); | |
1038 | a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); | |
1039 | d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); | |
1040 | c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); | |
1041 | b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); | |
1042 | a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); | |
1043 | d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); | |
1044 | c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); | |
1045 | b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); | |
1046 | a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); | |
1047 | d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); | |
1048 | c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); | |
1049 | b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); | |
1050 | ||
1051 | a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); | |
1052 | d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); | |
1053 | c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); | |
1054 | b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302); | |
1055 | a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); | |
1056 | d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); | |
1057 | c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); | |
1058 | b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); | |
1059 | a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); | |
1060 | d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); | |
1061 | c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); | |
1062 | b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); | |
1063 | a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); | |
1064 | d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); | |
1065 | c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); | |
1066 | b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); | |
1067 | ||
1068 | a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); | |
1069 | d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); | |
1070 | c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); | |
1071 | b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); | |
1072 | a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); | |
1073 | d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); | |
1074 | c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); | |
1075 | b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); | |
1076 | a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); | |
1077 | d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222); | |
1078 | c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); | |
1079 | b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); | |
1080 | a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); | |
1081 | d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); | |
1082 | c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); | |
1083 | b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); | |
1084 | ||
1085 | a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844); | |
1086 | d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); | |
1087 | c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); | |
1088 | b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); | |
1089 | a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); | |
1090 | d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); | |
1091 | c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); | |
1092 | b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); | |
1093 | a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); | |
1094 | d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); | |
1095 | c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); | |
1096 | b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); | |
1097 | a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); | |
1098 | d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); | |
1099 | c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); | |
1100 | b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); | |
1101 | ||
1102 | a = safe_add(a, olda); | |
1103 | b = safe_add(b, oldb); | |
1104 | c = safe_add(c, oldc); | |
1105 | d = safe_add(d, oldd); | |
1106 | } | |
1107 | return Array(a, b, c, d); | |
1108 | } | |
1109 | ||
1110 | /** | |
1111 | * These functions implement the four basic operations the algorithm uses. | |
1112 | */ | |
1113 | ||
1114 | function md5_cmn(q, a, b, x, s, t) { | |
1115 | return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); | |
1116 | } | |
1117 | ||
1118 | function md5_ff(a, b, c, d, x, s, t) { | |
1119 | return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); | |
1120 | } | |
1121 | ||
1122 | function md5_gg(a, b, c, d, x, s, t) { | |
1123 | return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); | |
1124 | } | |
1125 | ||
1126 | function md5_hh(a, b, c, d, x, s, t) { | |
1127 | return md5_cmn(b ^ c ^ d, a, b, x, s, t); | |
1128 | } | |
1129 | ||
1130 | function md5_ii(a, b, c, d, x, s, t) { | |
1131 | return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); | |
1132 | } | |
1133 | }, | |
1134 | /** | |
1135 | * @member Hashes | |
1136 | * @class Hashes.SHA1 | |
1137 | * @param {Object} [config] | |
1138 | * @constructor | |
1139 | * | |
1140 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1 | |
1141 | * Version 2.2 Copyright Paul Johnston 2000 - 2009. | |
1142 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
1143 | * See http://pajhome.org.uk/crypt/md5 for details. | |
1144 | */ | |
1145 | SHA1: function(options) { | |
1146 | /** | |
1147 | * Private config properties. You may need to tweak these to be compatible with | |
1148 | * the server-side, but the defaults work in most cases. | |
1149 | * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase} | |
1150 | */ | |
1151 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase | |
1152 | b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance | |
1153 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding | |
1154 | ||
1155 | // public methods | |
1156 | this.hex = function(s) { | |
1157 | return rstr2hex(rstr(s, utf8), hexcase); | |
1158 | }; | |
1159 | this.b64 = function(s) { | |
1160 | return rstr2b64(rstr(s, utf8), b64pad); | |
1161 | }; | |
1162 | this.any = function(s, e) { | |
1163 | return rstr2any(rstr(s, utf8), e); | |
1164 | }; | |
1165 | this.raw = function(s) { | |
1166 | return rstr(s, utf8); | |
1167 | }; | |
1168 | this.hex_hmac = function(k, d) { | |
1169 | return rstr2hex(rstr_hmac(k, d)); | |
1170 | }; | |
1171 | this.b64_hmac = function(k, d) { | |
1172 | return rstr2b64(rstr_hmac(k, d), b64pad); | |
1173 | }; | |
1174 | this.any_hmac = function(k, d, e) { | |
1175 | return rstr2any(rstr_hmac(k, d), e); | |
1176 | }; | |
1177 | /** | |
1178 | * Perform a simple self-test to see if the VM is working | |
1179 | * @return {String} Hexadecimal hash sample | |
1180 | * @public | |
1181 | */ | |
1182 | this.vm_test = function() { | |
1183 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; | |
1184 | }; | |
1185 | /** | |
1186 | * @description Enable/disable uppercase hexadecimal returned string | |
1187 | * @param {boolean} | |
1188 | * @return {Object} this | |
1189 | * @public | |
1190 | */ | |
1191 | this.setUpperCase = function(a) { | |
1192 | if (typeof a === 'boolean') { | |
1193 | hexcase = a; | |
1194 | } | |
1195 | return this; | |
1196 | }; | |
1197 | /** | |
1198 | * @description Defines a base64 pad string | |
1199 | * @param {string} Pad | |
1200 | * @return {Object} this | |
1201 | * @public | |
1202 | */ | |
1203 | this.setPad = function(a) { | |
1204 | b64pad = a || b64pad; | |
1205 | return this; | |
1206 | }; | |
1207 | /** | |
1208 | * @description Defines a base64 pad string | |
1209 | * @param {boolean} | |
1210 | * @return {Object} this | |
1211 | * @public | |
1212 | */ | |
1213 | this.setUTF8 = function(a) { | |
1214 | if (typeof a === 'boolean') { | |
1215 | utf8 = a; | |
1216 | } | |
1217 | return this; | |
1218 | }; | |
1219 | ||
1220 | // private methods | |
1221 | ||
1222 | /** | |
1223 | * Calculate the SHA-512 of a raw string | |
1224 | */ | |
1225 | ||
1226 | function rstr(s) { | |
1227 | s = (utf8) ? utf8Encode(s) : s; | |
1228 | return binb2rstr(binb(rstr2binb(s), s.length * 8)); | |
1229 | } | |
1230 | ||
1231 | /** | |
1232 | * Calculate the HMAC-SHA1 of a key and some data (raw strings) | |
1233 | */ | |
1234 | ||
1235 | function rstr_hmac(key, data) { | |
1236 | var bkey, ipad, opad, i, hash; | |
1237 | key = (utf8) ? utf8Encode(key) : key; | |
1238 | data = (utf8) ? utf8Encode(data) : data; | |
1239 | bkey = rstr2binb(key); | |
1240 | ||
1241 | if (bkey.length > 16) { | |
1242 | bkey = binb(bkey, key.length * 8); | |
1243 | } | |
1244 | ipad = Array(16), opad = Array(16); | |
1245 | for (i = 0; i < 16; i += 1) { | |
1246 | ipad[i] = bkey[i] ^ 0x36363636; | |
1247 | opad[i] = bkey[i] ^ 0x5C5C5C5C; | |
1248 | } | |
1249 | hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8); | |
1250 | return binb2rstr(binb(opad.concat(hash), 512 + 160)); | |
1251 | } | |
1252 | ||
1253 | /** | |
1254 | * Calculate the SHA-1 of an array of big-endian words, and a bit length | |
1255 | */ | |
1256 | ||
1257 | function binb(x, len) { | |
1258 | var i, j, t, olda, oldb, oldc, oldd, olde, | |
1259 | w = Array(80), | |
1260 | a = 1732584193, | |
1261 | b = -271733879, | |
1262 | c = -1732584194, | |
1263 | d = 271733878, | |
1264 | e = -1009589776; | |
1265 | ||
1266 | /* append padding */ | |
1267 | x[len >> 5] |= 0x80 << (24 - len % 32); | |
1268 | x[((len + 64 >> 9) << 4) + 15] = len; | |
1269 | ||
1270 | for (i = 0; i < x.length; i += 16) { | |
1271 | olda = a, | |
1272 | oldb = b; | |
1273 | oldc = c; | |
1274 | oldd = d; | |
1275 | olde = e; | |
1276 | ||
1277 | for (j = 0; j < 80; j += 1) { | |
1278 | if (j < 16) { | |
1279 | w[j] = x[i + j]; | |
1280 | } else { | |
1281 | w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); | |
1282 | } | |
1283 | t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), | |
1284 | safe_add(safe_add(e, w[j]), sha1_kt(j))); | |
1285 | e = d; | |
1286 | d = c; | |
1287 | c = bit_rol(b, 30); | |
1288 | b = a; | |
1289 | a = t; | |
1290 | } | |
1291 | ||
1292 | a = safe_add(a, olda); | |
1293 | b = safe_add(b, oldb); | |
1294 | c = safe_add(c, oldc); | |
1295 | d = safe_add(d, oldd); | |
1296 | e = safe_add(e, olde); | |
1297 | } | |
1298 | return Array(a, b, c, d, e); | |
1299 | } | |
1300 | ||
1301 | /** | |
1302 | * Perform the appropriate triplet combination function for the current | |
1303 | * iteration | |
1304 | */ | |
1305 | ||
1306 | function sha1_ft(t, b, c, d) { | |
1307 | if (t < 20) { | |
1308 | return (b & c) | ((~b) & d); | |
1309 | } | |
1310 | if (t < 40) { | |
1311 | return b ^ c ^ d; | |
1312 | } | |
1313 | if (t < 60) { | |
1314 | return (b & c) | (b & d) | (c & d); | |
1315 | } | |
1316 | return b ^ c ^ d; | |
1317 | } | |
1318 | ||
1319 | /** | |
1320 | * Determine the appropriate additive constant for the current iteration | |
1321 | */ | |
1322 | ||
1323 | function sha1_kt(t) { | |
1324 | return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : | |
1325 | (t < 60) ? -1894007588 : -899497514; | |
1326 | } | |
1327 | }, | |
1328 | /** | |
1329 | * @class Hashes.SHA256 | |
1330 | * @param {config} | |
1331 | * | |
1332 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2 | |
1333 | * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009. | |
1334 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
1335 | * See http://pajhome.org.uk/crypt/md5 for details. | |
1336 | * Also http://anmar.eu.org/projects/jssha2/ | |
1337 | */ | |
1338 | SHA256: function(options) { | |
1339 | /** | |
1340 | * Private properties configuration variables. You may need to tweak these to be compatible with | |
1341 | * the server-side, but the defaults work in most cases. | |
1342 | * @see this.setUpperCase() method | |
1343 | * @see this.setPad() method | |
1344 | */ | |
1345 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase */ | |
1346 | b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', | |
1347 | /* base-64 pad character. Default '=' for strict RFC compliance */ | |
1348 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, | |
1349 | /* enable/disable utf8 encoding */ | |
1350 | sha256_K; | |
1351 | ||
1352 | /* privileged (public) methods */ | |
1353 | this.hex = function(s) { | |
1354 | return rstr2hex(rstr(s, utf8)); | |
1355 | }; | |
1356 | this.b64 = function(s) { | |
1357 | return rstr2b64(rstr(s, utf8), b64pad); | |
1358 | }; | |
1359 | this.any = function(s, e) { | |
1360 | return rstr2any(rstr(s, utf8), e); | |
1361 | }; | |
1362 | this.raw = function(s) { | |
1363 | return rstr(s, utf8); | |
1364 | }; | |
1365 | this.hex_hmac = function(k, d) { | |
1366 | return rstr2hex(rstr_hmac(k, d)); | |
1367 | }; | |
1368 | this.b64_hmac = function(k, d) { | |
1369 | return rstr2b64(rstr_hmac(k, d), b64pad); | |
1370 | }; | |
1371 | this.any_hmac = function(k, d, e) { | |
1372 | return rstr2any(rstr_hmac(k, d), e); | |
1373 | }; | |
1374 | /** | |
1375 | * Perform a simple self-test to see if the VM is working | |
1376 | * @return {String} Hexadecimal hash sample | |
1377 | * @public | |
1378 | */ | |
1379 | this.vm_test = function() { | |
1380 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; | |
1381 | }; | |
1382 | /** | |
1383 | * Enable/disable uppercase hexadecimal returned string | |
1384 | * @param {boolean} | |
1385 | * @return {Object} this | |
1386 | * @public | |
1387 | */ | |
1388 | this.setUpperCase = function(a) { | |
1389 | if (typeof a === 'boolean') { | |
1390 | hexcase = a; | |
1391 | } | |
1392 | return this; | |
1393 | }; | |
1394 | /** | |
1395 | * @description Defines a base64 pad string | |
1396 | * @param {string} Pad | |
1397 | * @return {Object} this | |
1398 | * @public | |
1399 | */ | |
1400 | this.setPad = function(a) { | |
1401 | b64pad = a || b64pad; | |
1402 | return this; | |
1403 | }; | |
1404 | /** | |
1405 | * Defines a base64 pad string | |
1406 | * @param {boolean} | |
1407 | * @return {Object} this | |
1408 | * @public | |
1409 | */ | |
1410 | this.setUTF8 = function(a) { | |
1411 | if (typeof a === 'boolean') { | |
1412 | utf8 = a; | |
1413 | } | |
1414 | return this; | |
1415 | }; | |
1416 | ||
1417 | // private methods | |
1418 | ||
1419 | /** | |
1420 | * Calculate the SHA-512 of a raw string | |
1421 | */ | |
1422 | ||
1423 | function rstr(s, utf8) { | |
1424 | s = (utf8) ? utf8Encode(s) : s; | |
1425 | return binb2rstr(binb(rstr2binb(s), s.length * 8)); | |
1426 | } | |
1427 | ||
1428 | /** | |
1429 | * Calculate the HMAC-sha256 of a key and some data (raw strings) | |
1430 | */ | |
1431 | ||
1432 | function rstr_hmac(key, data) { | |
1433 | key = (utf8) ? utf8Encode(key) : key; | |
1434 | data = (utf8) ? utf8Encode(data) : data; | |
1435 | var hash, i = 0, | |
1436 | bkey = rstr2binb(key), | |
1437 | ipad = Array(16), | |
1438 | opad = Array(16); | |
1439 | ||
1440 | if (bkey.length > 16) { | |
1441 | bkey = binb(bkey, key.length * 8); | |
1442 | } | |
1443 | ||
1444 | for (; i < 16; i += 1) { | |
1445 | ipad[i] = bkey[i] ^ 0x36363636; | |
1446 | opad[i] = bkey[i] ^ 0x5C5C5C5C; | |
1447 | } | |
1448 | ||
1449 | hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8); | |
1450 | return binb2rstr(binb(opad.concat(hash), 512 + 256)); | |
1451 | } | |
1452 | ||
1453 | /* | |
1454 | * Main sha256 function, with its support functions | |
1455 | */ | |
1456 | ||
1457 | function sha256_S(X, n) { | |
1458 | return (X >>> n) | (X << (32 - n)); | |
1459 | } | |
1460 | ||
1461 | function sha256_R(X, n) { | |
1462 | return (X >>> n); | |
1463 | } | |
1464 | ||
1465 | function sha256_Ch(x, y, z) { | |
1466 | return ((x & y) ^ ((~x) & z)); | |
1467 | } | |
1468 | ||
1469 | function sha256_Maj(x, y, z) { | |
1470 | return ((x & y) ^ (x & z) ^ (y & z)); | |
1471 | } | |
1472 | ||
1473 | function sha256_Sigma0256(x) { | |
1474 | return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22)); | |
1475 | } | |
1476 | ||
1477 | function sha256_Sigma1256(x) { | |
1478 | return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25)); | |
1479 | } | |
1480 | ||
1481 | function sha256_Gamma0256(x) { | |
1482 | return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3)); | |
1483 | } | |
1484 | ||
1485 | function sha256_Gamma1256(x) { | |
1486 | return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10)); | |
1487 | } | |
1488 | ||
1489 | function sha256_Sigma0512(x) { | |
1490 | return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39)); | |
1491 | } | |
1492 | ||
1493 | function sha256_Sigma1512(x) { | |
1494 | return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41)); | |
1495 | } | |
1496 | ||
1497 | function sha256_Gamma0512(x) { | |
1498 | return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7)); | |
1499 | } | |
1500 | ||
1501 | function sha256_Gamma1512(x) { | |
1502 | return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6)); | |
1503 | } | |
1504 | ||
1505 | sha256_K = [ | |
1506 | 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987, | |
1507 | 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522, | |
1508 | 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585, | |
1509 | 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, | |
1510 | 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344, | |
1511 | 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, | |
1512 | 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998 | |
1513 | ]; | |
1514 | ||
1515 | function binb(m, l) { | |
1516 | var HASH = [1779033703, -1150833019, 1013904242, -1521486534, | |
1517 | 1359893119, -1694144372, 528734635, 1541459225 | |
1518 | ]; | |
1519 | var W = new Array(64); | |
1520 | var a, b, c, d, e, f, g, h; | |
1521 | var i, j, T1, T2; | |
1522 | ||
1523 | /* append padding */ | |
1524 | m[l >> 5] |= 0x80 << (24 - l % 32); | |
1525 | m[((l + 64 >> 9) << 4) + 15] = l; | |
1526 | ||
1527 | for (i = 0; i < m.length; i += 16) { | |
1528 | a = HASH[0]; | |
1529 | b = HASH[1]; | |
1530 | c = HASH[2]; | |
1531 | d = HASH[3]; | |
1532 | e = HASH[4]; | |
1533 | f = HASH[5]; | |
1534 | g = HASH[6]; | |
1535 | h = HASH[7]; | |
1536 | ||
1537 | for (j = 0; j < 64; j += 1) { | |
1538 | if (j < 16) { | |
1539 | W[j] = m[j + i]; | |
1540 | } else { | |
1541 | W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]), | |
1542 | sha256_Gamma0256(W[j - 15])), W[j - 16]); | |
1543 | } | |
1544 | ||
1545 | T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)), | |
1546 | sha256_K[j]), W[j]); | |
1547 | T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c)); | |
1548 | h = g; | |
1549 | g = f; | |
1550 | f = e; | |
1551 | e = safe_add(d, T1); | |
1552 | d = c; | |
1553 | c = b; | |
1554 | b = a; | |
1555 | a = safe_add(T1, T2); | |
1556 | } | |
1557 | ||
1558 | HASH[0] = safe_add(a, HASH[0]); | |
1559 | HASH[1] = safe_add(b, HASH[1]); | |
1560 | HASH[2] = safe_add(c, HASH[2]); | |
1561 | HASH[3] = safe_add(d, HASH[3]); | |
1562 | HASH[4] = safe_add(e, HASH[4]); | |
1563 | HASH[5] = safe_add(f, HASH[5]); | |
1564 | HASH[6] = safe_add(g, HASH[6]); | |
1565 | HASH[7] = safe_add(h, HASH[7]); | |
1566 | } | |
1567 | return HASH; | |
1568 | } | |
1569 | ||
1570 | }, | |
1571 | ||
1572 | /** | |
1573 | * @class Hashes.SHA512 | |
1574 | * @param {config} | |
1575 | * | |
1576 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2 | |
1577 | * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009. | |
1578 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
1579 | * See http://pajhome.org.uk/crypt/md5 for details. | |
1580 | */ | |
1581 | SHA512: function(options) { | |
1582 | /** | |
1583 | * Private properties configuration variables. You may need to tweak these to be compatible with | |
1584 | * the server-side, but the defaults work in most cases. | |
1585 | * @see this.setUpperCase() method | |
1586 | * @see this.setPad() method | |
1587 | */ | |
1588 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, | |
1589 | /* hexadecimal output case format. false - lowercase; true - uppercase */ | |
1590 | b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', | |
1591 | /* base-64 pad character. Default '=' for strict RFC compliance */ | |
1592 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, | |
1593 | /* enable/disable utf8 encoding */ | |
1594 | sha512_k; | |
1595 | ||
1596 | /* privileged (public) methods */ | |
1597 | this.hex = function(s) { | |
1598 | return rstr2hex(rstr(s)); | |
1599 | }; | |
1600 | this.b64 = function(s) { | |
1601 | return rstr2b64(rstr(s), b64pad); | |
1602 | }; | |
1603 | this.any = function(s, e) { | |
1604 | return rstr2any(rstr(s), e); | |
1605 | }; | |
1606 | this.raw = function(s) { | |
1607 | return rstr(s, utf8); | |
1608 | }; | |
1609 | this.hex_hmac = function(k, d) { | |
1610 | return rstr2hex(rstr_hmac(k, d)); | |
1611 | }; | |
1612 | this.b64_hmac = function(k, d) { | |
1613 | return rstr2b64(rstr_hmac(k, d), b64pad); | |
1614 | }; | |
1615 | this.any_hmac = function(k, d, e) { | |
1616 | return rstr2any(rstr_hmac(k, d), e); | |
1617 | }; | |
1618 | /** | |
1619 | * Perform a simple self-test to see if the VM is working | |
1620 | * @return {String} Hexadecimal hash sample | |
1621 | * @public | |
1622 | */ | |
1623 | this.vm_test = function() { | |
1624 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; | |
1625 | }; | |
1626 | /** | |
1627 | * @description Enable/disable uppercase hexadecimal returned string | |
1628 | * @param {boolean} | |
1629 | * @return {Object} this | |
1630 | * @public | |
1631 | */ | |
1632 | this.setUpperCase = function(a) { | |
1633 | if (typeof a === 'boolean') { | |
1634 | hexcase = a; | |
1635 | } | |
1636 | return this; | |
1637 | }; | |
1638 | /** | |
1639 | * @description Defines a base64 pad string | |
1640 | * @param {string} Pad | |
1641 | * @return {Object} this | |
1642 | * @public | |
1643 | */ | |
1644 | this.setPad = function(a) { | |
1645 | b64pad = a || b64pad; | |
1646 | return this; | |
1647 | }; | |
1648 | /** | |
1649 | * @description Defines a base64 pad string | |
1650 | * @param {boolean} | |
1651 | * @return {Object} this | |
1652 | * @public | |
1653 | */ | |
1654 | this.setUTF8 = function(a) { | |
1655 | if (typeof a === 'boolean') { | |
1656 | utf8 = a; | |
1657 | } | |
1658 | return this; | |
1659 | }; | |
1660 | ||
1661 | /* private methods */ | |
1662 | ||
1663 | /** | |
1664 | * Calculate the SHA-512 of a raw string | |
1665 | */ | |
1666 | ||
1667 | function rstr(s) { | |
1668 | s = (utf8) ? utf8Encode(s) : s; | |
1669 | return binb2rstr(binb(rstr2binb(s), s.length * 8)); | |
1670 | } | |
1671 | /* | |
1672 | * Calculate the HMAC-SHA-512 of a key and some data (raw strings) | |
1673 | */ | |
1674 | ||
1675 | function rstr_hmac(key, data) { | |
1676 | key = (utf8) ? utf8Encode(key) : key; | |
1677 | data = (utf8) ? utf8Encode(data) : data; | |
1678 | ||
1679 | var hash, i = 0, | |
1680 | bkey = rstr2binb(key), | |
1681 | ipad = Array(32), | |
1682 | opad = Array(32); | |
1683 | ||
1684 | if (bkey.length > 32) { | |
1685 | bkey = binb(bkey, key.length * 8); | |
1686 | } | |
1687 | ||
1688 | for (; i < 32; i += 1) { | |
1689 | ipad[i] = bkey[i] ^ 0x36363636; | |
1690 | opad[i] = bkey[i] ^ 0x5C5C5C5C; | |
1691 | } | |
1692 | ||
1693 | hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8); | |
1694 | return binb2rstr(binb(opad.concat(hash), 1024 + 512)); | |
1695 | } | |
1696 | ||
1697 | /** | |
1698 | * Calculate the SHA-512 of an array of big-endian dwords, and a bit length | |
1699 | */ | |
1700 | ||
1701 | function binb(x, len) { | |
1702 | var j, i, l, | |
1703 | W = new Array(80), | |
1704 | hash = new Array(16), | |
1705 | //Initial hash values | |
1706 | H = [ | |
1707 | new int64(0x6a09e667, -205731576), | |
1708 | new int64(-1150833019, -2067093701), | |
1709 | new int64(0x3c6ef372, -23791573), | |
1710 | new int64(-1521486534, 0x5f1d36f1), | |
1711 | new int64(0x510e527f, -1377402159), | |
1712 | new int64(-1694144372, 0x2b3e6c1f), | |
1713 | new int64(0x1f83d9ab, -79577749), | |
1714 | new int64(0x5be0cd19, 0x137e2179) | |
1715 | ], | |
1716 | T1 = new int64(0, 0), | |
1717 | T2 = new int64(0, 0), | |
1718 | a = new int64(0, 0), | |
1719 | b = new int64(0, 0), | |
1720 | c = new int64(0, 0), | |
1721 | d = new int64(0, 0), | |
1722 | e = new int64(0, 0), | |
1723 | f = new int64(0, 0), | |
1724 | g = new int64(0, 0), | |
1725 | h = new int64(0, 0), | |
1726 | //Temporary variables not specified by the document | |
1727 | s0 = new int64(0, 0), | |
1728 | s1 = new int64(0, 0), | |
1729 | Ch = new int64(0, 0), | |
1730 | Maj = new int64(0, 0), | |
1731 | r1 = new int64(0, 0), | |
1732 | r2 = new int64(0, 0), | |
1733 | r3 = new int64(0, 0); | |
1734 | ||
1735 | if (sha512_k === undefined) { | |
1736 | //SHA512 constants | |
1737 | sha512_k = [ | |
1738 | new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd), | |
1739 | new int64(-1245643825, -330482897), new int64(-373957723, -2121671748), | |
1740 | new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031), | |
1741 | new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736), | |
1742 | new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe), | |
1743 | new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302), | |
1744 | new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1), | |
1745 | new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428), | |
1746 | new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3), | |
1747 | new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65), | |
1748 | new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483), | |
1749 | new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459), | |
1750 | new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210), | |
1751 | new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340), | |
1752 | new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395), | |
1753 | new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70), | |
1754 | new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926), | |
1755 | new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473), | |
1756 | new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8), | |
1757 | new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b), | |
1758 | new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023), | |
1759 | new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30), | |
1760 | new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910), | |
1761 | new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8), | |
1762 | new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53), | |
1763 | new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016), | |
1764 | new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893), | |
1765 | new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397), | |
1766 | new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60), | |
1767 | new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec), | |
1768 | new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047), | |
1769 | new int64(-1090935817, -1295615723), new int64(-965641998, -479046869), | |
1770 | new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207), | |
1771 | new int64(-354779690, -840897762), new int64(-176337025, -294727304), | |
1772 | new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026), | |
1773 | new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b), | |
1774 | new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493), | |
1775 | new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620), | |
1776 | new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430), | |
1777 | new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817) | |
1778 | ]; | |
1779 | } | |
1780 | ||
1781 | for (i = 0; i < 80; i += 1) { | |
1782 | W[i] = new int64(0, 0); | |
1783 | } | |
1784 | ||
1785 | // append padding to the source string. The format is described in the FIPS. | |
1786 | x[len >> 5] |= 0x80 << (24 - (len & 0x1f)); | |
1787 | x[((len + 128 >> 10) << 5) + 31] = len; | |
1788 | l = x.length; | |
1789 | for (i = 0; i < l; i += 32) { //32 dwords is the block size | |
1790 | int64copy(a, H[0]); | |
1791 | int64copy(b, H[1]); | |
1792 | int64copy(c, H[2]); | |
1793 | int64copy(d, H[3]); | |
1794 | int64copy(e, H[4]); | |
1795 | int64copy(f, H[5]); | |
1796 | int64copy(g, H[6]); | |
1797 | int64copy(h, H[7]); | |
1798 | ||
1799 | for (j = 0; j < 16; j += 1) { | |
1800 | W[j].h = x[i + 2 * j]; | |
1801 | W[j].l = x[i + 2 * j + 1]; | |
1802 | } | |
1803 | ||
1804 | for (j = 16; j < 80; j += 1) { | |
1805 | //sigma1 | |
1806 | int64rrot(r1, W[j - 2], 19); | |
1807 | int64revrrot(r2, W[j - 2], 29); | |
1808 | int64shr(r3, W[j - 2], 6); | |
1809 | s1.l = r1.l ^ r2.l ^ r3.l; | |
1810 | s1.h = r1.h ^ r2.h ^ r3.h; | |
1811 | //sigma0 | |
1812 | int64rrot(r1, W[j - 15], 1); | |
1813 | int64rrot(r2, W[j - 15], 8); | |
1814 | int64shr(r3, W[j - 15], 7); | |
1815 | s0.l = r1.l ^ r2.l ^ r3.l; | |
1816 | s0.h = r1.h ^ r2.h ^ r3.h; | |
1817 | ||
1818 | int64add4(W[j], s1, W[j - 7], s0, W[j - 16]); | |
1819 | } | |
1820 | ||
1821 | for (j = 0; j < 80; j += 1) { | |
1822 | //Ch | |
1823 | Ch.l = (e.l & f.l) ^ (~e.l & g.l); | |
1824 | Ch.h = (e.h & f.h) ^ (~e.h & g.h); | |
1825 | ||
1826 | //Sigma1 | |
1827 | int64rrot(r1, e, 14); | |
1828 | int64rrot(r2, e, 18); | |
1829 | int64revrrot(r3, e, 9); | |
1830 | s1.l = r1.l ^ r2.l ^ r3.l; | |
1831 | s1.h = r1.h ^ r2.h ^ r3.h; | |
1832 | ||
1833 | //Sigma0 | |
1834 | int64rrot(r1, a, 28); | |
1835 | int64revrrot(r2, a, 2); | |
1836 | int64revrrot(r3, a, 7); | |
1837 | s0.l = r1.l ^ r2.l ^ r3.l; | |
1838 | s0.h = r1.h ^ r2.h ^ r3.h; | |
1839 | ||
1840 | //Maj | |
1841 | Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l); | |
1842 | Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h); | |
1843 | ||
1844 | int64add5(T1, h, s1, Ch, sha512_k[j], W[j]); | |
1845 | int64add(T2, s0, Maj); | |
1846 | ||
1847 | int64copy(h, g); | |
1848 | int64copy(g, f); | |
1849 | int64copy(f, e); | |
1850 | int64add(e, d, T1); | |
1851 | int64copy(d, c); | |
1852 | int64copy(c, b); | |
1853 | int64copy(b, a); | |
1854 | int64add(a, T1, T2); | |
1855 | } | |
1856 | int64add(H[0], H[0], a); | |
1857 | int64add(H[1], H[1], b); | |
1858 | int64add(H[2], H[2], c); | |
1859 | int64add(H[3], H[3], d); | |
1860 | int64add(H[4], H[4], e); | |
1861 | int64add(H[5], H[5], f); | |
1862 | int64add(H[6], H[6], g); | |
1863 | int64add(H[7], H[7], h); | |
1864 | } | |
1865 | ||
1866 | //represent the hash as an array of 32-bit dwords | |
1867 | for (i = 0; i < 8; i += 1) { | |
1868 | hash[2 * i] = H[i].h; | |
1869 | hash[2 * i + 1] = H[i].l; | |
1870 | } | |
1871 | return hash; | |
1872 | } | |
1873 | ||
1874 | //A constructor for 64-bit numbers | |
1875 | ||
1876 | function int64(h, l) { | |
1877 | this.h = h; | |
1878 | this.l = l; | |
1879 | //this.toString = int64toString; | |
1880 | } | |
1881 | ||
1882 | //Copies src into dst, assuming both are 64-bit numbers | |
1883 | ||
1884 | function int64copy(dst, src) { | |
1885 | dst.h = src.h; | |
1886 | dst.l = src.l; | |
1887 | } | |
1888 | ||
1889 | //Right-rotates a 64-bit number by shift | |
1890 | //Won't handle cases of shift>=32 | |
1891 | //The function revrrot() is for that | |
1892 | ||
1893 | function int64rrot(dst, x, shift) { | |
1894 | dst.l = (x.l >>> shift) | (x.h << (32 - shift)); | |
1895 | dst.h = (x.h >>> shift) | (x.l << (32 - shift)); | |
1896 | } | |
1897 | ||
1898 | //Reverses the dwords of the source and then rotates right by shift. | |
1899 | //This is equivalent to rotation by 32+shift | |
1900 | ||
1901 | function int64revrrot(dst, x, shift) { | |
1902 | dst.l = (x.h >>> shift) | (x.l << (32 - shift)); | |
1903 | dst.h = (x.l >>> shift) | (x.h << (32 - shift)); | |
1904 | } | |
1905 | ||
1906 | //Bitwise-shifts right a 64-bit number by shift | |
1907 | //Won't handle shift>=32, but it's never needed in SHA512 | |
1908 | ||
1909 | function int64shr(dst, x, shift) { | |
1910 | dst.l = (x.l >>> shift) | (x.h << (32 - shift)); | |
1911 | dst.h = (x.h >>> shift); | |
1912 | } | |
1913 | ||
1914 | //Adds two 64-bit numbers | |
1915 | //Like the original implementation, does not rely on 32-bit operations | |
1916 | ||
1917 | function int64add(dst, x, y) { | |
1918 | var w0 = (x.l & 0xffff) + (y.l & 0xffff); | |
1919 | var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16); | |
1920 | var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16); | |
1921 | var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16); | |
1922 | dst.l = (w0 & 0xffff) | (w1 << 16); | |
1923 | dst.h = (w2 & 0xffff) | (w3 << 16); | |
1924 | } | |
1925 | ||
1926 | //Same, except with 4 addends. Works faster than adding them one by one. | |
1927 | ||
1928 | function int64add4(dst, a, b, c, d) { | |
1929 | var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff); | |
1930 | var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16); | |
1931 | var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16); | |
1932 | var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16); | |
1933 | dst.l = (w0 & 0xffff) | (w1 << 16); | |
1934 | dst.h = (w2 & 0xffff) | (w3 << 16); | |
1935 | } | |
1936 | ||
1937 | //Same, except with 5 addends | |
1938 | ||
1939 | function int64add5(dst, a, b, c, d, e) { | |
1940 | var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff), | |
1941 | w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16), | |
1942 | w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16), | |
1943 | w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16); | |
1944 | dst.l = (w0 & 0xffff) | (w1 << 16); | |
1945 | dst.h = (w2 & 0xffff) | (w3 << 16); | |
1946 | } | |
1947 | }, | |
1948 | /** | |
1949 | * @class Hashes.RMD160 | |
1950 | * @constructor | |
1951 | * @param {Object} [config] | |
1952 | * | |
1953 | * A JavaScript implementation of the RIPEMD-160 Algorithm | |
1954 | * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009. | |
1955 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
1956 | * See http://pajhome.org.uk/crypt/md5 for details. | |
1957 | * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/ | |
1958 | */ | |
1959 | RMD160: function(options) { | |
1960 | /** | |
1961 | * Private properties configuration variables. You may need to tweak these to be compatible with | |
1962 | * the server-side, but the defaults work in most cases. | |
1963 | * @see this.setUpperCase() method | |
1964 | * @see this.setPad() method | |
1965 | */ | |
1966 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, | |
1967 | /* hexadecimal output case format. false - lowercase; true - uppercase */ | |
1968 | b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', | |
1969 | /* base-64 pad character. Default '=' for strict RFC compliance */ | |
1970 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, | |
1971 | /* enable/disable utf8 encoding */ | |
1972 | rmd160_r1 = [ | |
1973 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | |
1974 | 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, | |
1975 | 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, | |
1976 | 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, | |
1977 | 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 | |
1978 | ], | |
1979 | rmd160_r2 = [ | |
1980 | 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, | |
1981 | 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, | |
1982 | 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, | |
1983 | 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, | |
1984 | 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 | |
1985 | ], | |
1986 | rmd160_s1 = [ | |
1987 | 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, | |
1988 | 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, | |
1989 | 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, | |
1990 | 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, | |
1991 | 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 | |
1992 | ], | |
1993 | rmd160_s2 = [ | |
1994 | 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, | |
1995 | 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, | |
1996 | 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, | |
1997 | 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, | |
1998 | 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 | |
1999 | ]; | |
2000 | ||
2001 | /* privileged (public) methods */ | |
2002 | this.hex = function(s) { | |
2003 | return rstr2hex(rstr(s, utf8)); | |
2004 | }; | |
2005 | this.b64 = function(s) { | |
2006 | return rstr2b64(rstr(s, utf8), b64pad); | |
2007 | }; | |
2008 | this.any = function(s, e) { | |
2009 | return rstr2any(rstr(s, utf8), e); | |
2010 | }; | |
2011 | this.raw = function(s) { | |
2012 | return rstr(s, utf8); | |
2013 | }; | |
2014 | this.hex_hmac = function(k, d) { | |
2015 | return rstr2hex(rstr_hmac(k, d)); | |
2016 | }; | |
2017 | this.b64_hmac = function(k, d) { | |
2018 | return rstr2b64(rstr_hmac(k, d), b64pad); | |
2019 | }; | |
2020 | this.any_hmac = function(k, d, e) { | |
2021 | return rstr2any(rstr_hmac(k, d), e); | |
2022 | }; | |
2023 | /** | |
2024 | * Perform a simple self-test to see if the VM is working | |
2025 | * @return {String} Hexadecimal hash sample | |
2026 | * @public | |
2027 | */ | |
2028 | this.vm_test = function() { | |
2029 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; | |
2030 | }; | |
2031 | /** | |
2032 | * @description Enable/disable uppercase hexadecimal returned string | |
2033 | * @param {boolean} | |
2034 | * @return {Object} this | |
2035 | * @public | |
2036 | */ | |
2037 | this.setUpperCase = function(a) { | |
2038 | if (typeof a === 'boolean') { | |
2039 | hexcase = a; | |
2040 | } | |
2041 | return this; | |
2042 | }; | |
2043 | /** | |
2044 | * @description Defines a base64 pad string | |
2045 | * @param {string} Pad | |
2046 | * @return {Object} this | |
2047 | * @public | |
2048 | */ | |
2049 | this.setPad = function(a) { | |
2050 | if (typeof a !== 'undefined') { | |
2051 | b64pad = a; | |
2052 | } | |
2053 | return this; | |
2054 | }; | |
2055 | /** | |
2056 | * @description Defines a base64 pad string | |
2057 | * @param {boolean} | |
2058 | * @return {Object} this | |
2059 | * @public | |
2060 | */ | |
2061 | this.setUTF8 = function(a) { | |
2062 | if (typeof a === 'boolean') { | |
2063 | utf8 = a; | |
2064 | } | |
2065 | return this; | |
2066 | }; | |
2067 | ||
2068 | /* private methods */ | |
2069 | ||
2070 | /** | |
2071 | * Calculate the rmd160 of a raw string | |
2072 | */ | |
2073 | ||
2074 | function rstr(s) { | |
2075 | s = (utf8) ? utf8Encode(s) : s; | |
2076 | return binl2rstr(binl(rstr2binl(s), s.length * 8)); | |
2077 | } | |
2078 | ||
2079 | /** | |
2080 | * Calculate the HMAC-rmd160 of a key and some data (raw strings) | |
2081 | */ | |
2082 | ||
2083 | function rstr_hmac(key, data) { | |
2084 | key = (utf8) ? utf8Encode(key) : key; | |
2085 | data = (utf8) ? utf8Encode(data) : data; | |
2086 | var i, hash, | |
2087 | bkey = rstr2binl(key), | |
2088 | ipad = Array(16), | |
2089 | opad = Array(16); | |
2090 | ||
2091 | if (bkey.length > 16) { | |
2092 | bkey = binl(bkey, key.length * 8); | |
2093 | } | |
2094 | ||
2095 | for (i = 0; i < 16; i += 1) { | |
2096 | ipad[i] = bkey[i] ^ 0x36363636; | |
2097 | opad[i] = bkey[i] ^ 0x5C5C5C5C; | |
2098 | } | |
2099 | hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8); | |
2100 | return binl2rstr(binl(opad.concat(hash), 512 + 160)); | |
2101 | } | |
2102 | ||
2103 | /** | |
2104 | * Convert an array of little-endian words to a string | |
2105 | */ | |
2106 | ||
2107 | function binl2rstr(input) { | |
2108 | var i, output = '', | |
2109 | l = input.length * 32; | |
2110 | for (i = 0; i < l; i += 8) { | |
2111 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); | |
2112 | } | |
2113 | return output; | |
2114 | } | |
2115 | ||
2116 | /** | |
2117 | * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length. | |
2118 | */ | |
2119 | ||
2120 | function binl(x, len) { | |
2121 | var T, j, i, l, | |
2122 | h0 = 0x67452301, | |
2123 | h1 = 0xefcdab89, | |
2124 | h2 = 0x98badcfe, | |
2125 | h3 = 0x10325476, | |
2126 | h4 = 0xc3d2e1f0, | |
2127 | A1, B1, C1, D1, E1, | |
2128 | A2, B2, C2, D2, E2; | |
2129 | ||
2130 | /* append padding */ | |
2131 | x[len >> 5] |= 0x80 << (len % 32); | |
2132 | x[(((len + 64) >>> 9) << 4) + 14] = len; | |
2133 | l = x.length; | |
2134 | ||
2135 | for (i = 0; i < l; i += 16) { | |
2136 | A1 = A2 = h0; | |
2137 | B1 = B2 = h1; | |
2138 | C1 = C2 = h2; | |
2139 | D1 = D2 = h3; | |
2140 | E1 = E2 = h4; | |
2141 | for (j = 0; j <= 79; j += 1) { | |
2142 | T = safe_add(A1, rmd160_f(j, B1, C1, D1)); | |
2143 | T = safe_add(T, x[i + rmd160_r1[j]]); | |
2144 | T = safe_add(T, rmd160_K1(j)); | |
2145 | T = safe_add(bit_rol(T, rmd160_s1[j]), E1); | |
2146 | A1 = E1; | |
2147 | E1 = D1; | |
2148 | D1 = bit_rol(C1, 10); | |
2149 | C1 = B1; | |
2150 | B1 = T; | |
2151 | T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2)); | |
2152 | T = safe_add(T, x[i + rmd160_r2[j]]); | |
2153 | T = safe_add(T, rmd160_K2(j)); | |
2154 | T = safe_add(bit_rol(T, rmd160_s2[j]), E2); | |
2155 | A2 = E2; | |
2156 | E2 = D2; | |
2157 | D2 = bit_rol(C2, 10); | |
2158 | C2 = B2; | |
2159 | B2 = T; | |
2160 | } | |
2161 | ||
2162 | T = safe_add(h1, safe_add(C1, D2)); | |
2163 | h1 = safe_add(h2, safe_add(D1, E2)); | |
2164 | h2 = safe_add(h3, safe_add(E1, A2)); | |
2165 | h3 = safe_add(h4, safe_add(A1, B2)); | |
2166 | h4 = safe_add(h0, safe_add(B1, C2)); | |
2167 | h0 = T; | |
2168 | } | |
2169 | return [h0, h1, h2, h3, h4]; | |
2170 | } | |
2171 | ||
2172 | // specific algorithm methods | |
2173 | ||
2174 | function rmd160_f(j, x, y, z) { | |
2175 | return (0 <= j && j <= 15) ? (x ^ y ^ z) : | |
2176 | (16 <= j && j <= 31) ? (x & y) | (~x & z) : | |
2177 | (32 <= j && j <= 47) ? (x | ~y) ^ z : | |
2178 | (48 <= j && j <= 63) ? (x & z) | (y & ~z) : | |
2179 | (64 <= j && j <= 79) ? x ^ (y | ~z) : | |
2180 | 'rmd160_f: j out of range'; | |
2181 | } | |
2182 | ||
2183 | function rmd160_K1(j) { | |
2184 | return (0 <= j && j <= 15) ? 0x00000000 : | |
2185 | (16 <= j && j <= 31) ? 0x5a827999 : | |
2186 | (32 <= j && j <= 47) ? 0x6ed9eba1 : | |
2187 | (48 <= j && j <= 63) ? 0x8f1bbcdc : | |
2188 | (64 <= j && j <= 79) ? 0xa953fd4e : | |
2189 | 'rmd160_K1: j out of range'; | |
2190 | } | |
2191 | ||
2192 | function rmd160_K2(j) { | |
2193 | return (0 <= j && j <= 15) ? 0x50a28be6 : | |
2194 | (16 <= j && j <= 31) ? 0x5c4dd124 : | |
2195 | (32 <= j && j <= 47) ? 0x6d703ef3 : | |
2196 | (48 <= j && j <= 63) ? 0x7a6d76e9 : | |
2197 | (64 <= j && j <= 79) ? 0x00000000 : | |
2198 | 'rmd160_K2: j out of range'; | |
2199 | } | |
2200 | } | |
2201 | }; | |
2202 | ||
2203 | // exposes Hashes | |
2204 | (function(window, undefined) { | |
2205 | var freeExports = false; | |
2206 | if (typeof exports === 'object') { | |
2207 | freeExports = exports; | |
2208 | if (exports && typeof global === 'object' && global && global === global.global) { | |
2209 | window = global; | |
2210 | } | |
2211 | } | |
2212 | ||
2213 | if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { | |
2214 | // define as an anonymous module, so, through path mapping, it can be aliased | |
2215 | define(function() { | |
2216 | return Hashes; | |
2217 | }); | |
2218 | } else if (freeExports) { | |
2219 | // in Node.js or RingoJS v0.8.0+ | |
2220 | if (typeof module === 'object' && module && module.exports === freeExports) { | |
2221 | module.exports = Hashes; | |
2222 | } | |
2223 | // in Narwhal or RingoJS v0.7.0- | |
2224 | else { | |
2225 | freeExports.Hashes = Hashes; | |
2226 | } | |
2227 | } else { | |
2228 | // in a browser or Rhino | |
2229 | window.Hashes = Hashes; | |
2230 | } | |
2231 | }(this)); | |
2232 | }()); // IIFE | |
2233 | ||
2234 | })(window) | |
2235 | },{}],2:[function(require,module,exports){ | |
2236 | 'use strict'; | |
2237 | ||
2238 | var hashes = require('jshashes'), | |
2239 | xtend = require('xtend'), | |
2240 | sha1 = new hashes.SHA1(); | |
2241 | ||
2242 | var ohauth = {}; | |
2243 | ||
2244 | ohauth.qsString = function(obj) { | |
2245 | return Object.keys(obj).sort().map(function(key) { | |
2246 | return ohauth.percentEncode(key) + '=' + | |
2247 | ohauth.percentEncode(obj[key]); | |
2248 | }).join('&'); | |
2249 | }; | |
2250 | ||
2251 | ohauth.stringQs = function(str) { | |
2252 | return str.split('&').reduce(function(obj, pair){ | |
2253 | var parts = pair.split('='); | |
2254 | obj[decodeURIComponent(parts[0])] = (null === parts[1]) ? | |
2255 | '' : decodeURIComponent(parts[1]); | |
2256 | return obj; | |
2257 | }, {}); | |
2258 | }; | |
2259 | ||
2260 | ohauth.rawxhr = function(method, url, data, headers, callback) { | |
2261 | var xhr = new XMLHttpRequest(), | |
2262 | twoHundred = /^20\d$/; | |
2263 | xhr.onreadystatechange = function() { | |
2264 | if (4 == xhr.readyState && 0 !== xhr.status) { | |
2265 | if (twoHundred.test(xhr.status)) callback(null, xhr); | |
2266 | else return callback(xhr, null); | |
2267 | } | |
2268 | }; | |
2269 | xhr.onerror = function(e) { return callback(e, null); }; | |
2270 | xhr.open(method, url, true); | |
2271 | for (var h in headers) xhr.setRequestHeader(h, headers[h]); | |
2272 | xhr.send(data); | |
2273 | }; | |
2274 | ||
2275 | ohauth.xhr = function(method, url, auth, data, options, callback) { | |
2276 | var headers = (options && options.header) || { | |
2277 | 'Content-Type': 'application/x-www-form-urlencoded' | |
2278 | }; | |
2279 | headers.Authorization = 'OAuth ' + ohauth.authHeader(auth); | |
2280 | ohauth.rawxhr(method, url, data, headers, callback); | |
2281 | }; | |
2282 | ||
2283 | ohauth.nonce = function() { | |
2284 | for (var o = ''; o.length < 6;) { | |
2285 | o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)]; | |
2286 | } | |
2287 | return o; | |
2288 | }; | |
2289 | ||
2290 | ohauth.authHeader = function(obj) { | |
2291 | return Object.keys(obj).sort().map(function(key) { | |
2292 | return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"'; | |
2293 | }).join(', '); | |
2294 | }; | |
2295 | ||
2296 | ohauth.timestamp = function() { return ~~((+new Date()) / 1000); }; | |
2297 | ||
2298 | ohauth.percentEncode = function(s) { | |
2299 | return encodeURIComponent(s) | |
2300 | .replace(/\!/g, '%21').replace(/\'/g, '%27') | |
2301 | .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29'); | |
2302 | }; | |
2303 | ||
2304 | ohauth.baseString = function(method, url, params) { | |
2305 | if (params.oauth_signature) delete params.oauth_signature; | |
2306 | return [ | |
2307 | method, | |
2308 | ohauth.percentEncode(url), | |
2309 | ohauth.percentEncode(ohauth.qsString(params))].join('&'); | |
2310 | }; | |
2311 | ||
2312 | ohauth.signature = function(oauth_secret, token_secret, baseString) { | |
2313 | return sha1.b64_hmac( | |
2314 | ohauth.percentEncode(oauth_secret) + '&' + | |
2315 | ohauth.percentEncode(token_secret), | |
2316 | baseString); | |
2317 | }; | |
2318 | ||
2319 | /** | |
2320 | * Takes an options object for configuration (consumer_key, | |
2321 | * consumer_secret, version, signature_method, token) and returns a | |
2322 | * function that generates the Authorization header for given data. | |
2323 | * | |
2324 | * The returned function takes these parameters: | |
2325 | * - method: GET/POST/... | |
2326 | * - uri: full URI with protocol, port, path and query string | |
2327 | * - extra_params: any extra parameters (that are passed in the POST data), | |
2328 | * can be an object or a from-urlencoded string. | |
2329 | * | |
2330 | * Returned function returns full OAuth header with "OAuth" string in it. | |
2331 | */ | |
2332 | ||
2333 | ohauth.headerGenerator = function(options) { | |
2334 | options = options || {}; | |
2335 | var consumer_key = options.consumer_key || '', | |
2336 | consumer_secret = options.consumer_secret || '', | |
2337 | signature_method = options.signature_method || 'HMAC-SHA1', | |
2338 | version = options.version || '1.0', | |
2339 | token = options.token || ''; | |
2340 | ||
2341 | return function(method, uri, extra_params) { | |
2342 | method = method.toUpperCase(); | |
2343 | if (typeof extra_params === 'string' && extra_params.length > 0) { | |
2344 | extra_params = ohauth.stringQs(extra_params); | |
2345 | } | |
2346 | ||
2347 | var uri_parts = uri.split('?', 2), | |
2348 | base_uri = uri_parts[0]; | |
2349 | ||
2350 | var query_params = uri_parts.length === 2 ? | |
2351 | ohauth.stringQs(uri_parts[1]) : {}; | |
2352 | ||
2353 | var oauth_params = { | |
2354 | oauth_consumer_key: consumer_key, | |
2355 | oauth_signature_method: signature_method, | |
2356 | oauth_version: version, | |
2357 | oauth_timestamp: ohauth.timestamp(), | |
2358 | oauth_nonce: ohauth.nonce() | |
2359 | }; | |
2360 | ||
2361 | if (token) oauth_params.oauth_token = token; | |
2362 | ||
2363 | var all_params = xtend({}, oauth_params, query_params, extra_params), | |
2364 | base_str = ohauth.baseString(method, base_uri, all_params); | |
2365 | ||
2366 | oauth_params.oauth_signature = ohauth.signature(consumer_secret, token, base_str); | |
2367 | ||
2368 | return 'OAuth ' + ohauth.authHeader(oauth_params); | |
2369 | }; | |
2370 | }; | |
2371 | ||
2372 | module.exports = ohauth; | |
2373 | ||
2374 | },{"jshashes":7,"xtend":3}],6:[function(require,module,exports){ | |
2375 | module.exports = Object.keys || require('./shim'); | |
2376 | ||
2377 | ||
2378 | },{"./shim":8}],8:[function(require,module,exports){ | |
2379 | (function () { | |
2380 | "use strict"; | |
2381 | ||
2382 | // modified from https://github.com/kriskowal/es5-shim | |
2383 | var has = Object.prototype.hasOwnProperty, | |
2384 | is = require('is'), | |
2385 | forEach = require('foreach'), | |
2386 | hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), | |
2387 | dontEnums = [ | |
2388 | "toString", | |
2389 | "toLocaleString", | |
2390 | "valueOf", | |
2391 | "hasOwnProperty", | |
2392 | "isPrototypeOf", | |
2393 | "propertyIsEnumerable", | |
2394 | "constructor" | |
2395 | ], | |
2396 | keysShim; | |
2397 | ||
2398 | keysShim = function keys(object) { | |
2399 | if (!is.object(object) && !is.array(object)) { | |
2400 | throw new TypeError("Object.keys called on a non-object"); | |
2401 | } | |
2402 | ||
2403 | var name, theKeys = []; | |
2404 | for (name in object) { | |
2405 | if (has.call(object, name)) { | |
2406 | theKeys.push(name); | |
2407 | } | |
2408 | } | |
2409 | ||
2410 | if (hasDontEnumBug) { | |
2411 | forEach(dontEnums, function (dontEnum) { | |
2412 | if (has.call(object, dontEnum)) { | |
2413 | theKeys.push(dontEnum); | |
2414 | } | |
2415 | }); | |
2416 | } | |
2417 | return theKeys; | |
2418 | }; | |
2419 | ||
2420 | module.exports = keysShim; | |
2421 | }()); | |
2422 | ||
2423 | ||
2424 | },{"is":9,"foreach":10}],9:[function(require,module,exports){ | |
2425 | ||
2426 | /**! | |
2427 | * is | |
2428 | * the definitive JavaScript type testing library | |
2429 | * | |
2430 | * @copyright 2013 Enrico Marino | |
2431 | * @license MIT | |
2432 | */ | |
2433 | ||
2434 | var objProto = Object.prototype; | |
2435 | var owns = objProto.hasOwnProperty; | |
2436 | var toString = objProto.toString; | |
2437 | var isActualNaN = function (value) { | |
2438 | return value !== value; | |
2439 | }; | |
2440 | var NON_HOST_TYPES = { | |
2441 | "boolean": 1, | |
2442 | "number": 1, | |
2443 | "string": 1, | |
2444 | "undefined": 1 | |
2445 | }; | |
2446 | ||
2447 | /** | |
2448 | * Expose `is` | |
2449 | */ | |
2450 | ||
2451 | var is = module.exports = {}; | |
2452 | ||
2453 | /** | |
2454 | * Test general. | |
2455 | */ | |
2456 | ||
2457 | /** | |
2458 | * is.type | |
2459 | * Test if `value` is a type of `type`. | |
2460 | * | |
2461 | * @param {Mixed} value value to test | |
2462 | * @param {String} type type | |
2463 | * @return {Boolean} true if `value` is a type of `type`, false otherwise | |
2464 | * @api public | |
2465 | */ | |
2466 | ||
2467 | is.a = | |
2468 | is.type = function (value, type) { | |
2469 | return typeof value === type; | |
2470 | }; | |
2471 | ||
2472 | /** | |
2473 | * is.defined | |
2474 | * Test if `value` is defined. | |
2475 | * | |
2476 | * @param {Mixed} value value to test | |
2477 | * @return {Boolean} true if 'value' is defined, false otherwise | |
2478 | * @api public | |
2479 | */ | |
2480 | ||
2481 | is.defined = function (value) { | |
2482 | return value !== undefined; | |
2483 | }; | |
2484 | ||
2485 | /** | |
2486 | * is.empty | |
2487 | * Test if `value` is empty. | |
2488 | * | |
2489 | * @param {Mixed} value value to test | |
2490 | * @return {Boolean} true if `value` is empty, false otherwise | |
2491 | * @api public | |
2492 | */ | |
2493 | ||
2494 | is.empty = function (value) { | |
2495 | var type = toString.call(value); | |
2496 | var key; | |
2497 | ||
2498 | if ('[object Array]' === type || '[object Arguments]' === type) { | |
2499 | return value.length === 0; | |
2500 | } | |
2501 | ||
2502 | if ('[object Object]' === type) { | |
2503 | for (key in value) if (owns.call(value, key)) return false; | |
2504 | return true; | |
2505 | } | |
2506 | ||
2507 | if ('[object String]' === type) { | |
2508 | return '' === value; | |
2509 | } | |
2510 | ||
2511 | return false; | |
2512 | }; | |
2513 | ||
2514 | /** | |
2515 | * is.equal | |
2516 | * Test if `value` is equal to `other`. | |
2517 | * | |
2518 | * @param {Mixed} value value to test | |
2519 | * @param {Mixed} other value to compare with | |
2520 | * @return {Boolean} true if `value` is equal to `other`, false otherwise | |
2521 | */ | |
2522 | ||
2523 | is.equal = function (value, other) { | |
2524 | var type = toString.call(value) | |
2525 | var key; | |
2526 | ||
2527 | if (type !== toString.call(other)) { | |
2528 | return false; | |
2529 | } | |
2530 | ||
2531 | if ('[object Object]' === type) { | |
2532 | for (key in value) { | |
2533 | if (!is.equal(value[key], other[key])) { | |
2534 | return false; | |
2535 | } | |
2536 | } | |
2537 | return true; | |
2538 | } | |
2539 | ||
2540 | if ('[object Array]' === type) { | |
2541 | key = value.length; | |
2542 | if (key !== other.length) { | |
2543 | return false; | |
2544 | } | |
2545 | while (--key) { | |
2546 | if (!is.equal(value[key], other[key])) { | |
2547 | return false; | |
2548 | } | |
2549 | } | |
2550 | return true; | |
2551 | } | |
2552 | ||
2553 | if ('[object Function]' === type) { | |
2554 | return value.prototype === other.prototype; | |
2555 | } | |
2556 | ||
2557 | if ('[object Date]' === type) { | |
2558 | return value.getTime() === other.getTime(); | |
2559 | } | |
2560 | ||
2561 | return value === other; | |
2562 | }; | |
2563 | ||
2564 | /** | |
2565 | * is.hosted | |
2566 | * Test if `value` is hosted by `host`. | |
2567 | * | |
2568 | * @param {Mixed} value to test | |
2569 | * @param {Mixed} host host to test with | |
2570 | * @return {Boolean} true if `value` is hosted by `host`, false otherwise | |
2571 | * @api public | |
2572 | */ | |
2573 | ||
2574 | is.hosted = function (value, host) { | |
2575 | var type = typeof host[value]; | |
2576 | return type === 'object' ? !!host[value] : !NON_HOST_TYPES[type]; | |
2577 | }; | |
2578 | ||
2579 | /** | |
2580 | * is.instance | |
2581 | * Test if `value` is an instance of `constructor`. | |
2582 | * | |
2583 | * @param {Mixed} value value to test | |
2584 | * @return {Boolean} true if `value` is an instance of `constructor` | |
2585 | * @api public | |
2586 | */ | |
2587 | ||
2588 | is.instance = is['instanceof'] = function (value, constructor) { | |
2589 | return value instanceof constructor; | |
2590 | }; | |
2591 | ||
2592 | /** | |
2593 | * is.null | |
2594 | * Test if `value` is null. | |
2595 | * | |
2596 | * @param {Mixed} value value to test | |
2597 | * @return {Boolean} true if `value` is null, false otherwise | |
2598 | * @api public | |
2599 | */ | |
2600 | ||
2601 | is['null'] = function (value) { | |
2602 | return value === null; | |
2603 | }; | |
2604 | ||
2605 | /** | |
2606 | * is.undefined | |
2607 | * Test if `value` is undefined. | |
2608 | * | |
2609 | * @param {Mixed} value value to test | |
2610 | * @return {Boolean} true if `value` is undefined, false otherwise | |
2611 | * @api public | |
2612 | */ | |
2613 | ||
2614 | is.undefined = function (value) { | |
2615 | return value === undefined; | |
2616 | }; | |
2617 | ||
2618 | /** | |
2619 | * Test arguments. | |
2620 | */ | |
2621 | ||
2622 | /** | |
2623 | * is.arguments | |
2624 | * Test if `value` is an arguments object. | |
2625 | * | |
2626 | * @param {Mixed} value value to test | |
2627 | * @return {Boolean} true if `value` is an arguments object, false otherwise | |
2628 | * @api public | |
2629 | */ | |
2630 | ||
2631 | is.arguments = function (value) { | |
2632 | var isStandardArguments = '[object Arguments]' === toString.call(value); | |
2633 | var isOldArguments = !is.array(value) && is.arraylike(value) && is.object(value) && is.fn(value.callee); | |
2634 | return isStandardArguments || isOldArguments; | |
2635 | }; | |
2636 | ||
2637 | /** | |
2638 | * Test array. | |
2639 | */ | |
2640 | ||
2641 | /** | |
2642 | * is.array | |
2643 | * Test if 'value' is an array. | |
2644 | * | |
2645 | * @param {Mixed} value value to test | |
2646 | * @return {Boolean} true if `value` is an array, false otherwise | |
2647 | * @api public | |
2648 | */ | |
2649 | ||
2650 | is.array = function (value) { | |
2651 | return '[object Array]' === toString.call(value); | |
2652 | }; | |
2653 | ||
2654 | /** | |
2655 | * is.arguments.empty | |
2656 | * Test if `value` is an empty arguments object. | |
2657 | * | |
2658 | * @param {Mixed} value value to test | |
2659 | * @return {Boolean} true if `value` is an empty arguments object, false otherwise | |
2660 | * @api public | |
2661 | */ | |
2662 | is.arguments.empty = function (value) { | |
2663 | return is.arguments(value) && value.length === 0; | |
2664 | }; | |
2665 | ||
2666 | /** | |
2667 | * is.array.empty | |
2668 | * Test if `value` is an empty array. | |
2669 | * | |
2670 | * @param {Mixed} value value to test | |
2671 | * @return {Boolean} true if `value` is an empty array, false otherwise | |
2672 | * @api public | |
2673 | */ | |
2674 | is.array.empty = function (value) { | |
2675 | return is.array(value) && value.length === 0; | |
2676 | }; | |
2677 | ||
2678 | /** | |
2679 | * is.arraylike | |
2680 | * Test if `value` is an arraylike object. | |
2681 | * | |
2682 | * @param {Mixed} value value to test | |
2683 | * @return {Boolean} true if `value` is an arguments object, false otherwise | |
2684 | * @api public | |
2685 | */ | |
2686 | ||
2687 | is.arraylike = function (value) { | |
2688 | return !!value && !is.boolean(value) | |
2689 | && owns.call(value, 'length') | |
2690 | && isFinite(value.length) | |
2691 | && is.number(value.length) | |
2692 | && value.length >= 0; | |
2693 | }; | |
2694 | ||
2695 | /** | |
2696 | * Test boolean. | |
2697 | */ | |
2698 | ||
2699 | /** | |
2700 | * is.boolean | |
2701 | * Test if `value` is a boolean. | |
2702 | * | |
2703 | * @param {Mixed} value value to test | |
2704 | * @return {Boolean} true if `value` is a boolean, false otherwise | |
2705 | * @api public | |
2706 | */ | |
2707 | ||
2708 | is.boolean = function (value) { | |
2709 | return '[object Boolean]' === toString.call(value); | |
2710 | }; | |
2711 | ||
2712 | /** | |
2713 | * is.false | |
2714 | * Test if `value` is false. | |
2715 | * | |
2716 | * @param {Mixed} value value to test | |
2717 | * @return {Boolean} true if `value` is false, false otherwise | |
2718 | * @api public | |
2719 | */ | |
2720 | ||
2721 | is['false'] = function (value) { | |
2722 | return is.boolean(value) && (value === false || value.valueOf() === false); | |
2723 | }; | |
2724 | ||
2725 | /** | |
2726 | * is.true | |
2727 | * Test if `value` is true. | |
2728 | * | |
2729 | * @param {Mixed} value value to test | |
2730 | * @return {Boolean} true if `value` is true, false otherwise | |
2731 | * @api public | |
2732 | */ | |
2733 | ||
2734 | is['true'] = function (value) { | |
2735 | return is.boolean(value) && (value === true || value.valueOf() === true); | |
2736 | }; | |
2737 | ||
2738 | /** | |
2739 | * Test date. | |
2740 | */ | |
2741 | ||
2742 | /** | |
2743 | * is.date | |
2744 | * Test if `value` is a date. | |
2745 | * | |
2746 | * @param {Mixed} value value to test | |
2747 | * @return {Boolean} true if `value` is a date, false otherwise | |
2748 | * @api public | |
2749 | */ | |
2750 | ||
2751 | is.date = function (value) { | |
2752 | return '[object Date]' === toString.call(value); | |
2753 | }; | |
2754 | ||
2755 | /** | |
2756 | * Test element. | |
2757 | */ | |
2758 | ||
2759 | /** | |
2760 | * is.element | |
2761 | * Test if `value` is an html element. | |
2762 | * | |
2763 | * @param {Mixed} value value to test | |
2764 | * @return {Boolean} true if `value` is an HTML Element, false otherwise | |
2765 | * @api public | |
2766 | */ | |
2767 | ||
2768 | is.element = function (value) { | |
2769 | return value !== undefined | |
2770 | && typeof HTMLElement !== 'undefined' | |
2771 | && value instanceof HTMLElement | |
2772 | && value.nodeType === 1; | |
2773 | }; | |
2774 | ||
2775 | /** | |
2776 | * Test error. | |
2777 | */ | |
2778 | ||
2779 | /** | |
2780 | * is.error | |
2781 | * Test if `value` is an error object. | |
2782 | * | |
2783 | * @param {Mixed} value value to test | |
2784 | * @return {Boolean} true if `value` is an error object, false otherwise | |
2785 | * @api public | |
2786 | */ | |
2787 | ||
2788 | is.error = function (value) { | |
2789 | return '[object Error]' === toString.call(value); | |
2790 | }; | |
2791 | ||
2792 | /** | |
2793 | * Test function. | |
2794 | */ | |
2795 | ||
2796 | /** | |
2797 | * is.fn / is.function (deprecated) | |
2798 | * Test if `value` is a function. | |
2799 | * | |
2800 | * @param {Mixed} value value to test | |
2801 | * @return {Boolean} true if `value` is a function, false otherwise | |
2802 | * @api public | |
2803 | */ | |
2804 | ||
2805 | is.fn = is['function'] = function (value) { | |
2806 | var isAlert = typeof window !== 'undefined' && value === window.alert; | |
2807 | return isAlert || '[object Function]' === toString.call(value); | |
2808 | }; | |
2809 | ||
2810 | /** | |
2811 | * Test number. | |
2812 | */ | |
2813 | ||
2814 | /** | |
2815 | * is.number | |
2816 | * Test if `value` is a number. | |
2817 | * | |
2818 | * @param {Mixed} value value to test | |
2819 | * @return {Boolean} true if `value` is a number, false otherwise | |
2820 | * @api public | |
2821 | */ | |
2822 | ||
2823 | is.number = function (value) { | |
2824 | return '[object Number]' === toString.call(value); | |
2825 | }; | |
2826 | ||
2827 | /** | |
2828 | * is.infinite | |
2829 | * Test if `value` is positive or negative infinity. | |
2830 | * | |
2831 | * @param {Mixed} value value to test | |
2832 | * @return {Boolean} true if `value` is positive or negative Infinity, false otherwise | |
2833 | * @api public | |
2834 | */ | |
2835 | is.infinite = function (value) { | |
2836 | return value === Infinity || value === -Infinity; | |
2837 | }; | |
2838 | ||
2839 | /** | |
2840 | * is.decimal | |
2841 | * Test if `value` is a decimal number. | |
2842 | * | |
2843 | * @param {Mixed} value value to test | |
2844 | * @return {Boolean} true if `value` is a decimal number, false otherwise | |
2845 | * @api public | |
2846 | */ | |
2847 | ||
2848 | is.decimal = function (value) { | |
2849 | return is.number(value) && !isActualNaN(value) && !is.infinite(value) && value % 1 !== 0; | |
2850 | }; | |
2851 | ||
2852 | /** | |
2853 | * is.divisibleBy | |
2854 | * Test if `value` is divisible by `n`. | |
2855 | * | |
2856 | * @param {Number} value value to test | |
2857 | * @param {Number} n dividend | |
2858 | * @return {Boolean} true if `value` is divisible by `n`, false otherwise | |
2859 | * @api public | |
2860 | */ | |
2861 | ||
2862 | is.divisibleBy = function (value, n) { | |
2863 | var isDividendInfinite = is.infinite(value); | |
2864 | var isDivisorInfinite = is.infinite(n); | |
2865 | var isNonZeroNumber = is.number(value) && !isActualNaN(value) && is.number(n) && !isActualNaN(n) && n !== 0; | |
2866 | return isDividendInfinite || isDivisorInfinite || (isNonZeroNumber && value % n === 0); | |
2867 | }; | |
2868 | ||
2869 | /** | |
2870 | * is.int | |
2871 | * Test if `value` is an integer. | |
2872 | * | |
2873 | * @param value to test | |
2874 | * @return {Boolean} true if `value` is an integer, false otherwise | |
2875 | * @api public | |
2876 | */ | |
2877 | ||
2878 | is.int = function (value) { | |
2879 | return is.number(value) && !isActualNaN(value) && value % 1 === 0; | |
2880 | }; | |
2881 | ||
2882 | /** | |
2883 | * is.maximum | |
2884 | * Test if `value` is greater than 'others' values. | |
2885 | * | |
2886 | * @param {Number} value value to test | |
2887 | * @param {Array} others values to compare with | |
2888 | * @return {Boolean} true if `value` is greater than `others` values | |
2889 | * @api public | |
2890 | */ | |
2891 | ||
2892 | is.maximum = function (value, others) { | |
2893 | if (isActualNaN(value)) { | |
2894 | throw new TypeError('NaN is not a valid value'); | |
2895 | } else if (!is.arraylike(others)) { | |
2896 | throw new TypeError('second argument must be array-like'); | |
2897 | } | |
2898 | var len = others.length; | |
2899 | ||
2900 | while (--len >= 0) { | |
2901 | if (value < others[len]) { | |
2902 | return false; | |
2903 | } | |
2904 | } | |
2905 | ||
2906 | return true; | |
2907 | }; | |
2908 | ||
2909 | /** | |
2910 | * is.minimum | |
2911 | * Test if `value` is less than `others` values. | |
2912 | * | |
2913 | * @param {Number} value value to test | |
2914 | * @param {Array} others values to compare with | |
2915 | * @return {Boolean} true if `value` is less than `others` values | |
2916 | * @api public | |
2917 | */ | |
2918 | ||
2919 | is.minimum = function (value, others) { | |
2920 | if (isActualNaN(value)) { | |
2921 | throw new TypeError('NaN is not a valid value'); | |
2922 | } else if (!is.arraylike(others)) { | |
2923 | throw new TypeError('second argument must be array-like'); | |
2924 | } | |
2925 | var len = others.length; | |
2926 | ||
2927 | while (--len >= 0) { | |
2928 | if (value > others[len]) { | |
2929 | return false; | |
2930 | } | |
2931 | } | |
2932 | ||
2933 | return true; | |
2934 | }; | |
2935 | ||
2936 | /** | |
2937 | * is.nan | |
2938 | * Test if `value` is not a number. | |
2939 | * | |
2940 | * @param {Mixed} value value to test | |
2941 | * @return {Boolean} true if `value` is not a number, false otherwise | |
2942 | * @api public | |
2943 | */ | |
2944 | ||
2945 | is.nan = function (value) { | |
2946 | return !is.number(value) || value !== value; | |
2947 | }; | |
2948 | ||
2949 | /** | |
2950 | * is.even | |
2951 | * Test if `value` is an even number. | |
2952 | * | |
2953 | * @param {Number} value value to test | |
2954 | * @return {Boolean} true if `value` is an even number, false otherwise | |
2955 | * @api public | |
2956 | */ | |
2957 | ||
2958 | is.even = function (value) { | |
2959 | return is.infinite(value) || (is.number(value) && value === value && value % 2 === 0); | |
2960 | }; | |
2961 | ||
2962 | /** | |
2963 | * is.odd | |
2964 | * Test if `value` is an odd number. | |
2965 | * | |
2966 | * @param {Number} value value to test | |
2967 | * @return {Boolean} true if `value` is an odd number, false otherwise | |
2968 | * @api public | |
2969 | */ | |
2970 | ||
2971 | is.odd = function (value) { | |
2972 | return is.infinite(value) || (is.number(value) && value === value && value % 2 !== 0); | |
2973 | }; | |
2974 | ||
2975 | /** | |
2976 | * is.ge | |
2977 | * Test if `value` is greater than or equal to `other`. | |
2978 | * | |
2979 | * @param {Number} value value to test | |
2980 | * @param {Number} other value to compare with | |
2981 | * @return {Boolean} | |
2982 | * @api public | |
2983 | */ | |
2984 | ||
2985 | is.ge = function (value, other) { | |
2986 | if (isActualNaN(value) || isActualNaN(other)) { | |
2987 | throw new TypeError('NaN is not a valid value'); | |
2988 | } | |
2989 | return !is.infinite(value) && !is.infinite(other) && value >= other; | |
2990 | }; | |
2991 | ||
2992 | /** | |
2993 | * is.gt | |
2994 | * Test if `value` is greater than `other`. | |
2995 | * | |
2996 | * @param {Number} value value to test | |
2997 | * @param {Number} other value to compare with | |
2998 | * @return {Boolean} | |
2999 | * @api public | |
3000 | */ | |
3001 | ||
3002 | is.gt = function (value, other) { | |
3003 | if (isActualNaN(value) || isActualNaN(other)) { | |
3004 | throw new TypeError('NaN is not a valid value'); | |
3005 | } | |
3006 | return !is.infinite(value) && !is.infinite(other) && value > other; | |
3007 | }; | |
3008 | ||
3009 | /** | |
3010 | * is.le | |
3011 | * Test if `value` is less than or equal to `other`. | |
3012 | * | |
3013 | * @param {Number} value value to test | |
3014 | * @param {Number} other value to compare with | |
3015 | * @return {Boolean} if 'value' is less than or equal to 'other' | |
3016 | * @api public | |
3017 | */ | |
3018 | ||
3019 | is.le = function (value, other) { | |
3020 | if (isActualNaN(value) || isActualNaN(other)) { | |
3021 | throw new TypeError('NaN is not a valid value'); | |
3022 | } | |
3023 | return !is.infinite(value) && !is.infinite(other) && value <= other; | |
3024 | }; | |
3025 | ||
3026 | /** | |
3027 | * is.lt | |
3028 | * Test if `value` is less than `other`. | |
3029 | * | |
3030 | * @param {Number} value value to test | |
3031 | * @param {Number} other value to compare with | |
3032 | * @return {Boolean} if `value` is less than `other` | |
3033 | * @api public | |
3034 | */ | |
3035 | ||
3036 | is.lt = function (value, other) { | |
3037 | if (isActualNaN(value) || isActualNaN(other)) { | |
3038 | throw new TypeError('NaN is not a valid value'); | |
3039 | } | |
3040 | return !is.infinite(value) && !is.infinite(other) && value < other; | |
3041 | }; | |
3042 | ||
3043 | /** | |
3044 | * is.within | |
3045 | * Test if `value` is within `start` and `finish`. | |
3046 | * | |
3047 | * @param {Number} value value to test | |
3048 | * @param {Number} start lower bound | |
3049 | * @param {Number} finish upper bound | |
3050 | * @return {Boolean} true if 'value' is is within 'start' and 'finish' | |
3051 | * @api public | |
3052 | */ | |
3053 | is.within = function (value, start, finish) { | |
3054 | if (isActualNaN(value) || isActualNaN(start) || isActualNaN(finish)) { | |
3055 | throw new TypeError('NaN is not a valid value'); | |
3056 | } else if (!is.number(value) || !is.number(start) || !is.number(finish)) { | |
3057 | throw new TypeError('all arguments must be numbers'); | |
3058 | } | |
3059 | var isAnyInfinite = is.infinite(value) || is.infinite(start) || is.infinite(finish); | |
3060 | return isAnyInfinite || (value >= start && value <= finish); | |
3061 | }; | |
3062 | ||
3063 | /** | |
3064 | * Test object. | |
3065 | */ | |
3066 | ||
3067 | /** | |
3068 | * is.object | |
3069 | * Test if `value` is an object. | |
3070 | * | |
3071 | * @param {Mixed} value value to test | |
3072 | * @return {Boolean} true if `value` is an object, false otherwise | |
3073 | * @api public | |
3074 | */ | |
3075 | ||
3076 | is.object = function (value) { | |
3077 | return value && '[object Object]' === toString.call(value); | |
3078 | }; | |
3079 | ||
3080 | /** | |
3081 | * is.hash | |
3082 | * Test if `value` is a hash - a plain object literal. | |
3083 | * | |
3084 | * @param {Mixed} value value to test | |
3085 | * @return {Boolean} true if `value` is a hash, false otherwise | |
3086 | * @api public | |
3087 | */ | |
3088 | ||
3089 | is.hash = function (value) { | |
3090 | return is.object(value) && value.constructor === Object && !value.nodeType && !value.setInterval; | |
3091 | }; | |
3092 | ||
3093 | /** | |
3094 | * Test regexp. | |
3095 | */ | |
3096 | ||
3097 | /** | |
3098 | * is.regexp | |
3099 | * Test if `value` is a regular expression. | |
3100 | * | |
3101 | * @param {Mixed} value value to test | |
3102 | * @return {Boolean} true if `value` is a regexp, false otherwise | |
3103 | * @api public | |
3104 | */ | |
3105 | ||
3106 | is.regexp = function (value) { | |
3107 | return '[object RegExp]' === toString.call(value); | |
3108 | }; | |
3109 | ||
3110 | /** | |
3111 | * Test string. | |
3112 | */ | |
3113 | ||
3114 | /** | |
3115 | * is.string | |
3116 | * Test if `value` is a string. | |
3117 | * | |
3118 | * @param {Mixed} value value to test | |
3119 | * @return {Boolean} true if 'value' is a string, false otherwise | |
3120 | * @api public | |
3121 | */ | |
3122 | ||
3123 | is.string = function (value) { | |
3124 | return '[object String]' === toString.call(value); | |
3125 | }; | |
3126 | ||
3127 | ||
3128 | },{}],10:[function(require,module,exports){ | |
3129 | ||
3130 | var hasOwn = Object.prototype.hasOwnProperty; | |
3131 | var toString = Object.prototype.toString; | |
3132 | ||
3133 | module.exports = function forEach (obj, fn, ctx) { | |
3134 | if (toString.call(fn) !== '[object Function]') { | |
3135 | throw new TypeError('iterator must be a function'); | |
3136 | } | |
3137 | var l = obj.length; | |
3138 | if (l === +l) { | |
3139 | for (var i = 0; i < l; i++) { | |
3140 | fn.call(ctx, obj[i], i, obj); | |
3141 | } | |
3142 | } else { | |
3143 | for (var k in obj) { | |
3144 | if (hasOwn.call(obj, k)) { | |
3145 | fn.call(ctx, obj[k], k, obj); | |
3146 | } | |
3147 | } | |
3148 | } | |
3149 | }; | |
3150 | ||
3151 | ||
3152 | },{}]},{},[1])(1) | |
3153 | }); | |
3154 | ; |