关于JS端对文件进行SHA1计算的问题

ipromise_u 2015-10-09 02:52:41
RT

有一个比较棘手的问题. 上传文件. 使用md5进行唯一验证并不正确. 因为两个不同的文件也有可能会出现 MD5一样的问题.

http://www.wooyun.org/bugs/wooyun-2010-015881
http://www.izhuyue.com/644.html

所以为了判断唯一. 我需要对文件进行sha1的计算.
为什么一定需要在前台JS端进行sha1的计算呢?因为如果是服务器端的. 那么需要将文件完成传输之后才能进行判断 .这样就不能寄到在像秒传一样的.

服务器端的. 参考了七牛的sha1计算
https://github.com/qiniu/qetag/blob/master/QETag.java
但是他的前端是基于nodejs而实现的. 这里好像无法做到集成. 还请大家帮忙看看
感谢了
...全文
780 1 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
qq_28839497 2017-08-30
这个file.sha1_hash 没法return 出来,是因为onload在之后执行吗?
回复
ipromise_u 2017-08-09
大家的邮件我有时候来不急查看. 弄了一个分享链接.大家直接在这里下载吧 https://pan.baidu.com/s/1bps6MdT
回复
huberyliu 2016-12-12
求dome遇到类似的问题 邮箱 huanself@126.com 不胜感激
回复
ipromise_u 2015-11-17
问题已经解决. 我写了一个demo 如果谁遇到同样的问题.可以问我要demo 看我个人资料联系. 我到时候邮件发你
回复
ipromise_u 2015-10-10

/*
 * Crypto-JS v2.5.1
 * http://code.google.com/p/crypto-js/
 * (c) 2009-2011 by Jeff Mott. All rights reserved.
 * http://code.google.com/p/crypto-js/wiki/License
 */
(typeof Crypto == "undefined" || !Crypto.util)
		&& function() {
			var e = self.Crypto = {}, g = e.util = {
				rotl : function(a, b) {
					return a << b | a >>> 32 - b
				},
				rotr : function(a, b) {
					return a << 32 - b | a >>> b
				},
				endian : function(a) {
					if (a.constructor == Number)
						return g.rotl(a, 8) & 16711935 | g.rotl(a, 24)
								& 4278255360;
					for ( var b = 0; b < a.length; b++)
						a[b] = g.endian(a[b]);
					return a
				},
				randomBytes : function(a) {
					for ( var b = []; a > 0; a--)
						b.push(Math.floor(Math.random() * 256));
					return b
				},
				bytesToWords : function(a) {
					for ( var b = [], c = 0, d = 0; c < a.length; c++, d += 8)
						b[d >>> 5] |= a[c] << 24 - d % 32;
					return b
				},
				wordsToBytes : function(a) {
					for ( var b = [], c = 0; c < a.length * 32; c += 8)
						b.push(a[c >>> 5] >>> 24 - c % 32 & 255);
					return b
				},
				bytesToHex : function(a) {
					for ( var b = [], c = 0; c < a.length; c++)
						b.push((a[c] >>> 4).toString(16)), b.push((a[c] & 15)
								.toString(16));
					return b.join("")
				},
				hexToBytes : function(a) {
					for ( var b = [], c = 0; c < a.length; c += 2)
						b.push(parseInt(a.substr(c, 2), 16));
					return b
				},
				bytesToBase64 : function(a) {
					if (typeof btoa == "function")
						return btoa(f.bytesToString(a));
					for ( var b = [], c = 0; c < a.length; c += 3)
						for ( var d = a[c] << 16 | a[c + 1] << 8 | a[c + 2], e = 0; e < 4; e++)
							c * 8 + e * 6 <= a.length * 8 ? b
									.push("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
											.charAt(d >>> 6 * (3 - e) & 63))
									: b.push("=");
					return b.join("")
				},
				base64ToBytes : function(a) {
					if (typeof atob == "function")
						return f.stringToBytes(atob(a));
					for ( var a = a.replace(/[^A-Z0-9+\/]/ig, ""), b = [], c = 0, d = 0; c < a.length; d = ++c % 4)
						d != 0
								&& b
										.push(("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
												.indexOf(a.charAt(c - 1)) & Math
												.pow(2, -2 * d + 8) - 1) << d * 2
												| "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
														.indexOf(a.charAt(c)) >>> 6 - d * 2);
					return b
				}
			}, e = e.charenc = {};
			e.UTF8 = {
				stringToBytes : function(a) {
					return f.stringToBytes(unescape(encodeURIComponent(a)))
				},
				bytesToString : function(a) {
					return decodeURIComponent(escape(f.bytesToString(a)))
				}
			};
			var f = e.Binary = {
				stringToBytes : function(a) {
					for ( var b = [], c = 0; c < a.length; c++)
						b.push(a.charCodeAt(c) & 255);
					return b
				},
				bytesToString : function(a) {
					for ( var b = [], c = 0; c < a.length; c++)
						b.push(String.fromCharCode(a[c]));
					return b.join("")
				}
			}
		}();

/*
 * sha1File v1.0.1 https://github.com/dwsVad/sha1File (c) 2014 by Protsenko
 * Vadim. All rights reserved.
 * https://github.com/dwsVad/sha1File/blob/master/LICENSE
 */
function sha1File(settings) {
	var hash = [ 1732584193, -271733879, -1732584194, 271733878, -1009589776 ];
	var buffer = 1024 * 16 * 64;
	var sha1 = function(block, hash) {
		var words = [];
		var count_parts = 16;
		var h0 = hash[0], h1 = hash[1], h2 = hash[2], h3 = hash[3], h4 = hash[4];
		for ( var i = 0; i < block.length; i += count_parts) {
			var th0 = h0, th1 = h1, th2 = h2, th3 = h3, th4 = h4;
			for ( var j = 0; j < 80; j++) {
				if (j < count_parts)
					words[j] = block[i + j] | 0;
				else {
					var n = words[j - 3] ^ words[j - 8] ^ words[j - 14]
							^ words[j - count_parts];
					words[j] = (n << 1) | (n >>> 31);
				}
				var f, k;
				if (j < 20) {
					f = (h1 & h2 | ~h1 & h3);
					k = 1518500249;
				} else if (j < 40) {
					f = (h1 ^ h2 ^ h3);
					k = 1859775393;
				} else if (j < 60) {
					f = (h1 & h2 | h1 & h3 | h2 & h3);
					k = -1894007588;
				} else {
					f = (h1 ^ h2 ^ h3);
					k = -899497514;
				}

				var t = ((h0 << 5) | (h0 >>> 27)) + h4 + (words[j] >>> 0) + f
						+ k;
				h4 = h3;
				h3 = h2;
				h2 = (h1 << 30) | (h1 >>> 2);
				h1 = h0;
				h0 = t;
			}
			h0 = (h0 + th0) | 0;
			h1 = (h1 + th1) | 0;
			h2 = (h2 + th2) | 0;
			h3 = (h3 + th3) | 0;
			h4 = (h4 + th4) | 0;
		}
		return [ h0, h1, h2, h3, h4 ];
	}

	var run = function(file, inStart, inEnd) {
		var end = Math.min(inEnd, file.size);
		var start = inStart;
		var reader = new FileReader();
		reader.onload = function() {
			file.sha1_progress = (end * 100 / file.size);

			var block = Crypto.util.bytesToWords(new Uint8Array(
					event.target.result));

			if (end === file.size) {
				var bTotal, bLeft, bTotalH, bTotalL;
				bTotal = file.size * 8;
				bLeft = (end - start) * 8;

				bTotalH = Math.floor(bTotal / 0x100000000);
				bTotalL = bTotal & 0xFFFFFFFF;

				// Padding
				block[bLeft >>> 5] |= 0x80 << (24 - bLeft % 32);
				block[((bLeft + 64 >>> 9) << 4) + 14] = bTotalH;
				block[((bLeft + 64 >>> 9) << 4) + 15] = bTotalL;

				hash = sha1(block, hash);
				file.sha1_hash = Crypto.util.bytesToHex(Crypto.util
						.wordsToBytes(hash));
			} else {
				hash = sha1(block, hash);
				start += buffer;
				end += buffer;
				run(file, start, end);
			}
		}
		var blob = file.slice(start, end);
		reader.readAsArrayBuffer(blob.source);
	}

	var utf8to16 = function(str) {
		var out, i, len, c;
		var char2, char3;

		out = "";
		len = str.length;
		i = 0;
		while (i < len) {
			c = str.charCodeAt(i++);
			switch (c >> 4) {
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
				// 0xxxxxxx
				out += str.charAt(i - 1);
				break;
			case 12:
			case 13:
				// 110x xxxx 10xx xxxx
				char2 = str.charCodeAt(i++);
				out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
				break;
			case 14:
				// 1110 xxxx 10xx xxxx 10xx xxxx
				char2 = str.charCodeAt(i++);
				char3 = str.charCodeAt(i++);
				out += String.fromCharCode(((c & 0x0F) << 12)
						| ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
				break;
			}
		}

		return out;
	}

	var utf16to8 = function(str) {
		var out, i, len, c;

		out = "";
		len = str.length;
		for (i = 0; i < len; i++) {
			c = str.charCodeAt(i);
			if ((c >= 0x0001) && (c <= 0x007F)) {
				out += str.charAt(i);
			} else if (c > 0x07FF) {
				out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
				out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
				out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
			} else {
				out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
				out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
			}
		}
		return out;
	}

	var checkApi = function() {
		if ((typeof File == 'undefined'))
			return false;

		if (!File.prototype.slice) {
			if (File.prototype.webkitSlice)
				File.prototype.slice = File.prototype.webkitSlice;
			else if (File.prototype.mozSlice)
				File.prototype.slice = File.prototype.mozSlice;
		}

		if (!window.File || !window.FileReader || !window.FileList
				|| !window.Blob || !File.prototype.slice)
			return false;

		return true;
	}

	if (checkApi()) {
		run(settings, 0, buffer);
	} else
		return false;
}

这是git上面看到的. 他算出来的sha1值 不对. 有没有大神呢
回复
相关推荐
发帖
Web 开发
创建于2007-09-28

8.0w+

社区成员

Java Web 开发
申请成为版主
帖子事件
创建了帖子
2015-10-09 02:52
社区公告
暂无公告