├── .gitignore ├── test ├── test.js ├── index.html └── index.js ├── gulpfile.js ├── package.json ├── README.md └── src ├── jquery.crc32.min.js └── jquery.crc32.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | .DS_Store -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $('#upload').crc32(function(err, code) { 3 | if (err) { 4 | console.log(err); 5 | } else { 6 | $('.result').text(code); 7 | } 8 | }); 9 | }); -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var gulp = require('gulp'); 4 | var rename = require('gulp-rename'); 5 | var uglify = require('gulp-uglify'); 6 | 7 | gulp.task('default', function() { 8 | return gulp.src('src/jquery.crc32.js') 9 | .pipe(uglify()) 10 | .pipe(rename({ extname: '.min.js' })) 11 | .pipe(gulp.dest('src/')); 12 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-crc32", 3 | "version": "1.0.0", 4 | "description": "A jquery plugin for generate crc32 code.", 5 | "main": "src/jquery.crc32.min.js", 6 | "author": { 7 | "name": "Spikef", 8 | "email": "Spikef@foxmail.com" 9 | }, 10 | "license": "MIT", 11 | "devDependencies": { 12 | "gulp": "^3.9.1", 13 | "gulp-rename": "^1.2.2", 14 | "gulp-uglify": "^1.5.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jquery-crc32 2 | 3 | 上传文件前检验文件的crc32码,配合服务器接口, 可以用于防止上传重复文件, 实现所谓秒传。 4 | 5 | 对于超过5M的文件, 默认只检验前5M数据的crc32码。 6 | 7 | 很明显, 这需要你的浏览器支持FileReader和TypedArray。 8 | 9 | ## 示例 10 | 11 | ```javascript 12 | $(document).ready(function() { 13 | $('#upload').crc32(function(err, code) { 14 | if (err) { 15 | console.log(err); 16 | } else { 17 | $('.result').text(code); 18 | } 19 | }); 20 | }); 21 | ``` 22 | 23 | ## 说明 24 | 25 | 你妹的, 面试被人家嫌弃不会写jquery插件了。写个给你看好了, 这算什么了不起的技能么? -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jquery.crc32 test 6 | 7 | 8 | 9 | 15 | 16 | 17 |
18 | 你选择的文件的crc32检验码为: 19 |
20 |
21 | 22 |
23 | 24 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | var http = require('http'); 4 | 5 | http.createServer(function (req, res) { 6 | if (req.url === 'favicon.ico') return; 7 | 8 | var filename = req.url.replace('/', '').replace('src/', '../src/'); 9 | var realPath = path.resolve(__dirname, filename); 10 | var extension = path.extname(realPath); 11 | var mimeType = mimeTypes[extension] || 'text/plain'; 12 | 13 | fs.exists(realPath, function(exists){ 14 | if (!exists){ 15 | res.writeHead(404, { 16 | 'Content-Type': mimeType 17 | }); 18 | 19 | res.end(); 20 | } else { 21 | var file = fs.createReadStream(realPath); 22 | 23 | res.writeHead(200, { 24 | 'Content-Type': mimeType 25 | }); 26 | file.on('data', res.write.bind(res)); 27 | file.on('close', res.end.bind(res)); 28 | file.on('error', function(err){ 29 | res.writeHead(500, { 30 | 'Content-Type': mimeType 31 | }); 32 | 33 | res.end(); 34 | }); 35 | } 36 | }); 37 | }) 38 | .listen(6100); 39 | 40 | console.log('Server running at http://localhost:6100/'); 41 | 42 | var mimeTypes = { 43 | '.txt': 'text/plain', 44 | '.html': 'text/html', 45 | '.css': 'text/css', 46 | '.xml': 'application/xml', 47 | '.json': 'application/json', 48 | '.js': 'application/javascript', 49 | '.jpg': 'image/jpeg', 50 | '.jpeg': 'image/jpeg', 51 | '.gif': 'image/gif', 52 | '.png': 'image/png', 53 | '.svg': 'image/svg+xml' 54 | }; -------------------------------------------------------------------------------- /src/jquery.crc32.min.js: -------------------------------------------------------------------------------- 1 | !function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e(require("jquery")):e(jQuery)}(function(e){var r=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]),t=function(e){for(var t=-1,o=new Uint8Array(e),i=0;i>>8^r[255&(t^o[i])];var n=(t^-1)>>>0;return n.toString(16).toUpperCase()},o=File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice,i=5242880;e.fn.crc32=function(e){this.on("change",function(){if(this.files&&this.files[0]){var r=this.files[0],n=r.size,a=new FileReader;a.onerror=function(r){switch(r.target.error.code){case r.target.error.NOT_FOUND_ERR:e("File Not Found!");break;case r.target.error.NOT_READABLE_ERR:e("File is not readable");break;case r.target.error.ABORT_ERR:break;default:e("An error occurred reading this file.")}},a.onabort=function(r){e("File read cancelled")},a.onload=function(r){var o=t(r.target.result);e(null,o)},n>i&&(r=o.call(r,0,i)),a.readAsArrayBuffer(r)}})}}); -------------------------------------------------------------------------------- /src/jquery.crc32.js: -------------------------------------------------------------------------------- 1 | (function (factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | // AMD (Register as an anonymous module) 4 | define(['jquery'], factory); 5 | } else if (typeof exports === 'object') { 6 | // Node/CommonJS 7 | module.exports = factory(require('jquery')); 8 | } else { 9 | // Browser globals 10 | factory(jQuery); 11 | } 12 | }(function ($) { 13 | var table = new Uint32Array([ 14 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 15 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 16 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 17 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 18 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 19 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 20 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 21 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 22 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 23 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 24 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 25 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 26 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 27 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 28 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 29 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 30 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 31 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 32 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 33 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 34 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 35 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 36 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 37 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 38 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 39 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 40 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 41 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 42 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 43 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 44 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 45 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 46 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 47 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 48 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 49 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 50 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 51 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 52 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 53 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 54 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 55 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 56 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 57 | ]); 58 | 59 | var crc32 = function(ab) { 60 | var crc = 0 ^ (-1); 61 | var data = new Uint8Array(ab); 62 | 63 | for(var i = 0; i < ab.byteLength; i++){ 64 | crc = (crc >>> 8) ^ table[(crc ^ data[i]) & 0xFF]; 65 | } 66 | 67 | var value = (crc ^ (-1)) >>> 0; 68 | 69 | return value.toString(16).toUpperCase(); 70 | }; 71 | 72 | var slice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice; 73 | var maxSize = 5242880; 74 | 75 | $.fn.crc32 = function(callback) { 76 | this.on('change', function() { 77 | if (this.files && this.files[0]) { 78 | var file = this.files[0]; 79 | var size = file.size; 80 | 81 | var reader = new FileReader(); 82 | reader.onerror = function (e) { 83 | switch(e.target.error.code) { 84 | case e.target.error.NOT_FOUND_ERR: 85 | callback('File Not Found!'); 86 | break; 87 | case e.target.error.NOT_READABLE_ERR: 88 | callback('File is not readable'); 89 | break; 90 | case e.target.error.ABORT_ERR: 91 | break; // noop 92 | default: 93 | callback('An error occurred reading this file.'); 94 | } 95 | }; 96 | reader.onabort = function(e) { 97 | callback('File read cancelled'); 98 | }; 99 | reader.onload = function(e) { 100 | var code = crc32(e.target.result); 101 | callback(null, code); 102 | }; 103 | 104 | if (size > maxSize) file = slice.call(file, 0, maxSize); 105 | 106 | reader.readAsArrayBuffer(file); 107 | } 108 | }); 109 | } 110 | })); --------------------------------------------------------------------------------