diff --git a/demo.html b/demo.html
new file mode 100644
index 0000000..c3a0098
--- /dev/null
+++ b/demo.html
@@ -0,0 +1,3 @@
+
+
+Go to fp's Web Page!
\ No newline at end of file
diff --git a/fp.js b/fp.js
index 802eb1f..5ac5b62 100644
--- a/fp.js
+++ b/fp.js
@@ -1,3 +1,265 @@
-var fp_arr=window.location.href.split("://");fp_arr=fp_arr[1].split("/");fp_arr=fp_arr[0].split(".");fp_arr[0]=fp_arr[fp_arr.length-2]+"."+fp_arr[fp_arr.length-1];(function($){function safeAdd(x,y){var lsw=(x&65535)+(y&65535);var msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&65535)}function bitRotateLeft(num,cnt){return(num<>>(32-cnt))}function md5cmn(q,a,b,x,s,t){return safeAdd(bitRotateLeft(safeAdd(safeAdd(a,q),safeAdd(x,t)),s),b)}function md5ff(a,b,c,d,x,s,t){return md5cmn((b&c)|(~b&d),a,b,x,s,t)}function md5gg(a,b,c,d,x,s,t){return md5cmn((b&d)|(c&~d),a,b,x,s,t)}function md5hh(a,b,c,d,x,s,t){return md5cmn(b^c^d,a,b,x,s,t)}function md5ii(a,b,c,d,x,s,t){return md5cmn(c^(b|~d),a,b,x,s,t)}function binlMD5(x,len){x[len>>5]|=128<<(len%32);x[((len+64)>>>9<<4)+14]=len;var i;var olda;var oldb;var oldc;var oldd;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;for(i=0;i>5]>>>(i%32))&255)}return output}function rstr2binl(input){var i;var output=[];output[(input.length>>2)-1]=undefined;for(i=0;i>5]|=(input.charCodeAt(i/8)&255)<<(i%32)}return output}function rstrMD5(s){return binl2rstr(binlMD5(rstr2binl(s),s.length*8))}function rstrHMACMD5(key,data){var i;var bkey=rstr2binl(key);var ipad=[];var opad=[];var hash;ipad[15]=opad[15]=undefined;if(bkey.length>16){bkey=binlMD5(bkey,key.length*8)}for(i=0;i<16;i+=1){ipad[i]=bkey[i]^909522486;opad[i]=bkey[i]^1549556828}hash=binlMD5(ipad.concat(rstr2binl(data)),512+data.length*8);return binl2rstr(binlMD5(opad.concat(hash),512+128))}function rstr2hex(input){var hexTab="0123456789abcdef";var output="";var x;var i;for(i=0;i>>4)&15)+hexTab.charAt(x&15)}return output}function str2rstrUTF8(input){return unescape(encodeURIComponent(input))}function rawMD5(s){return rstrMD5(str2rstrUTF8(s))}function hexMD5(s){return rstr2hex(rawMD5(s))}function rawHMACMD5(k,d){return rstrHMACMD5(str2rstrUTF8(k),str2rstrUTF8(d))}function hexHMACMD5(k,d){return rstr2hex(rawHMACMD5(k,d))}function md5(string,key,raw){if(!key){if(!raw){return hexMD5(string)}return rawMD5(string)}if(!raw){return hexHMACMD5(key,string)}return rawHMACMD5(key,string)}if(typeof define==="function"&&define.amd){define(function(){return md5
-})}else{if(typeof module==="object"&&module.exports){module.exports=md5}else{$.md5=md5}}})(this);(function(scope){var Fingerprint=function(options){var nativeForEach,nativeMap;nativeForEach=Array.prototype.forEach;nativeMap=Array.prototype.map;this.each=function(obj,iterator,context){if(obj===null){return}if(nativeForEach&&obj.forEach===nativeForEach){obj.forEach(iterator,context)}else{if(obj.length===+obj.length){for(var i=0,l=obj.length;i>>16)*c1)&65535)<<16)))&4294967295;k1=(k1<<15)|(k1>>>17);k1=((((k1&65535)*c2)+((((k1>>>16)*c2)&65535)<<16)))&4294967295;h1^=k1;h1=(h1<<13)|(h1>>>19);h1b=((((h1&65535)*5)+((((h1>>>16)*5)&65535)<<16)))&4294967295;h1=(((h1b&65535)+27492)+((((h1b>>>16)+58964)&65535)<<16))}k1=0;switch(remainder){case 3:k1^=(key.charCodeAt(i+2)&255)<<16;case 2:k1^=(key.charCodeAt(i+1)&255)<<8;case 1:k1^=(key.charCodeAt(i)&255);k1=(((k1&65535)*c1)+((((k1>>>16)*c1)&65535)<<16))&4294967295;k1=(k1<<15)|(k1>>>17);k1=(((k1&65535)*c2)+((((k1>>>16)*c2)&65535)<<16))&4294967295;h1^=k1}h1^=key.length;h1^=h1>>>16;h1=(((h1&65535)*2246822507)+((((h1>>>16)*2246822507)&65535)<<16))&4294967295;h1^=h1>>>13;h1=((((h1&65535)*3266489909)+((((h1>>>16)*3266489909)&65535)<<16)))&4294967295;h1^=h1>>>16;return h1>>>0},hasLocalStorage:function(){try{return !!scope.localStorage}catch(e){return true}},hasSessionStorage:function(){try{return !!scope.sessionStorage}catch(e){return true}},isCanvasSupported:function(){var elem=document.createElement("canvas");return !!(elem.getContext&&elem.getContext("2d"))},isIE:function(){if(navigator.appName==="Microsoft Internet Explorer"){return true}else{if(navigator.appName==="Netscape"&&/Trident/.test(navigator.userAgent)){return true}}return false},getPluginsString:function(){if(this.isIE()){return this.getIEPluginsString()}else{return this.getRegularPluginsString()}},getRegularPluginsString:function(){return this.map(navigator.plugins,function(p){var mimeTypes=this.map(p,function(mt){return[mt.type,mt.suffixes].join("~")}).join(",");return[p.name,p.description,mimeTypes].join("::")},this).join(";")},getIEPluginsString:function(){var names=["ShockwaveFlash.ShockwaveFlash","AcroPDF.PDF","PDF.PdfCtrl","QuickTime.QuickTime","rmocx.RealPlayer G2 Control","rmocx.RealPlayer G2 Control.1","RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)","RealVideo.RealVideo(tm) ActiveX Control (32-bit)","RealPlayer","SWCtl.SWCtl","WMPlayer.OCX","AgControl.AgControl","Skype.Detection"];if(this.ie_activex&&scope.ActiveXObject){return this.map(names,function(name){try{new ActiveXObject(name);return name}catch(e){return null}}).join(";")}else{return""}},getScreenResolution:function(){return[screen.height,screen.width]},getCanvasFingerprint:function(){var canvas=document.createElement("canvas");var ctx=canvas.getContext("2d");var txt="http://valve.github.io";ctx.textBaseline="top";ctx.font="14px 'Arial'";ctx.textBaseline="alphabetic";ctx.fillStyle="#f60";ctx.fillRect(125,1,62,20);ctx.fillStyle="#069";ctx.fillText(txt,2,15);ctx.fillStyle="rgba(102, 204, 0, 0.7)";ctx.fillText(txt,4,17);return canvas.toDataURL()}};if(typeof module==="object"&&typeof exports==="object"){module.exports=Fingerprint
-}scope.Fingerprint=Fingerprint})(window);var fp=md5(new Fingerprint({canvas:true}+_fp(fp_arr[0])).get()).slice(0,8);function _fp(txt){var canvas=document.createElement("canvas");var ctx=canvas.getContext("2d");if(!txt){txt="https://security.yimian.xyz/"}ctx.textBaseline="top";ctx.font="15px 'Arial'";ctx.textBaseline="yimian";ctx.fillStyle="#f66";ctx.fillRect(125,1,52,20);ctx.fillStyle="#039";ctx.fillText(txt,2,15);ctx.fillStyle="rgba(102, 204, 0, 0.7)";ctx.fillText(txt,4,17);var b64=canvas.toDataURL();b64=b64.replace("data:image/png;base64,","");var bin=atob(b64).slice(-16,-12);var i,l,o="",n;bin+="";for(i=0,l=bin.length;i>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;
+ k1 = (k1 << 15) | (k1 >>> 17);
+ k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;
+
+ h1 ^= k1;
+ h1 = (h1 << 13) | (h1 >>> 19);
+ h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;
+ h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));
+ }
+
+ k1 = 0;
+
+ switch (remainder) {
+ case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
+ case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
+ case 1: k1 ^= (key.charCodeAt(i) & 0xff);
+
+ k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
+ k1 = (k1 << 15) | (k1 >>> 17);
+ k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
+ h1 ^= k1;
+ }
+
+ h1 ^= key.length;
+
+ h1 ^= h1 >>> 16;
+ h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
+ h1 ^= h1 >>> 13;
+ h1 = ((((h1 & 0xffff) * 0xd2b2ae35) + ((((h1 >>> 16) * 0xd2b2ae35) & 0xffff) << 16))) & 0xffffffff;
+ h1 ^= h1 >>> 16;
+ //transfer result to 8 words
+ var r = ['1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
+
+ return h1, r[h1 & 31 + 2] + r[(h1 & (31 << 6))>>>6] + r[(h1 & (31 << 13)) >>> 13 + 4] + r[(h1 & (31 << 20)) >>> 20]+ r[(h1 & (31 << 27)) >>> 27 + 1]+ r[(h1 & (31 << 35)) >>> 35]+ r[(h1 & (31 << 42)) >>> 42 +2]+ r[(h1 & (31 << 51)) >>> 51 + 3];
+ },
+
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=781447
+ hasLocalStorage: function () {
+ try{
+ return !!window.localStorage;
+ } catch(e) {
+ return true; // SecurityError when referencing it means it exists
+ }
+ },
+
+ hasSessionStorage: function () {
+ try{
+ return !!window.sessionStorage;
+ } catch(e) {
+ return true; // SecurityError when referencing it means it exists
+ }
+ },
+
+ hasIndexDb: function () {
+ try{
+ return !!window.indexedDB;
+ } catch(e) {
+ return true; // SecurityError when referencing it means it exists
+ }
+ },
+
+ isCanvasSupported: function () {
+ var elem = document.createElement('canvas');
+ return !!(elem.getContext && elem.getContext('2d'));
+ },
+
+ isIE: function () {
+ if(navigator.appName === 'Microsoft Internet Explorer') {
+ return true;
+ } else if(navigator.appName === 'Netscape' && /Trident/.test(navigator.userAgent)){// IE 11
+ return true;
+ }
+ return false;
+ },
+
+ getPluginsString: function () {
+ if(this.isIE() && this.ie_activex){
+ return this.getIEPluginsString();
+ } else {
+ return this.getRegularPluginsString();
+ }
+ },
+
+ getRegularPluginsString: function () {
+ return this.map(navigator.plugins, function (p) {
+ var mimeTypes = this.map(p, function(mt){
+ return [mt.type, mt.suffixes].join('~');
+ }).join(',');
+ return [p.name, p.description, mimeTypes].join('::');
+ }, this).join(';');
+ },
+
+ getIEPluginsString: function () {
+ if(window.ActiveXObject){
+ var names = ['ShockwaveFlash.ShockwaveFlash',//flash plugin
+ 'AcroPDF.PDF', // Adobe PDF reader 7+
+ 'PDF.PdfCtrl', // Adobe PDF reader 6 and earlier, brrr
+ 'QuickTime.QuickTime', // QuickTime
+ // 5 versions of real players
+ 'rmocx.RealPlayer G2 Control',
+ 'rmocx.RealPlayer G2 Control.1',
+ 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
+ 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)',
+ 'RealPlayer',
+ 'SWCtl.SWCtl', // ShockWave player
+ 'WMPlayer.OCX', // Windows media player
+ 'AgControl.AgControl', // Silverlight
+ 'Skype.Detection'];
+
+ // starting to detect plugins in IE
+ return this.map(names, function(name){
+ try{
+ new ActiveXObject(name);
+ return name;
+ } catch(e){
+ return null;
+ }
+ }).join(';');
+ } else {
+ return ""; // behavior prior version 0.5.0, not breaking backwards compat.
+ }
+ },
+
+ getScreenResolution: function () {
+ var resolution;
+ if(this.screen_orientation){
+ resolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height];
+ }else{
+ resolution = [screen.height, screen.width];
+ }
+ return resolution;
+ },
+
+ getCanvasFingerprint: function () {
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+ var txt = 'https://fp.yimian.xyz';
+ ctx.textBaseline = "top";
+ ctx.font = "14px 'Arial'";
+ ctx.textBaseline = "alphabetic";
+ ctx.fillStyle = "#f60";
+ ctx.fillRect(125,1,62,20);
+ ctx.fillStyle = "#069";
+ ctx.fillText(txt, 2, 15);
+ ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
+ ctx.fillText(txt, 4, 17);
+ return canvas.toDataURL();
+ }
+ };
+
+
+ return Fingerprint;
+
+});
+
+var fp = new fp().get();
\ No newline at end of file
diff --git a/fp.js.map b/fp.js.map
deleted file mode 100644
index 4f3fae5..0000000
--- a/fp.js.map
+++ /dev/null
@@ -1,553 +0,0 @@
-var fp_arr =window.location.href.split("://");
-fp_arr=fp_arr[1].split("/");
-fp_arr=fp_arr[0].split(".");
-fp_arr[0]=fp_arr[fp_arr.length-2]+'.'+fp_arr[fp_arr.length-1];
-
-/* global define */
-
-(function ($) {
- 'use strict'
-
- /*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
- function safeAdd (x, y) {
- var lsw = (x & 0xffff) + (y & 0xffff)
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
- return (msw << 16) | (lsw & 0xffff)
- }
-
- /*
- * Bitwise rotate a 32-bit number to the left.
- */
- function bitRotateLeft (num, cnt) {
- return (num << cnt) | (num >>> (32 - cnt))
- }
-
- /*
- * These functions implement the four basic operations the algorithm uses.
- */
- function md5cmn (q, a, b, x, s, t) {
- return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b)
- }
- function md5ff (a, b, c, d, x, s, t) {
- return md5cmn((b & c) | (~b & d), a, b, x, s, t)
- }
- function md5gg (a, b, c, d, x, s, t) {
- return md5cmn((b & d) | (c & ~d), a, b, x, s, t)
- }
- function md5hh (a, b, c, d, x, s, t) {
- return md5cmn(b ^ c ^ d, a, b, x, s, t)
- }
- function md5ii (a, b, c, d, x, s, t) {
- return md5cmn(c ^ (b | ~d), a, b, x, s, t)
- }
-
- /*
- * Calculate the MD5 of an array of little-endian words, and a bit length.
- */
- function binlMD5 (x, len) {
- /* append padding */
- x[len >> 5] |= 0x80 << (len % 32)
- x[((len + 64) >>> 9 << 4) + 14] = len
-
- var i
- var olda
- var oldb
- var oldc
- var oldd
- var a = 1732584193
- var b = -271733879
- var c = -1732584194
- var d = 271733878
-
- for (i = 0; i < x.length; i += 16) {
- olda = a
- oldb = b
- oldc = c
- oldd = d
-
- a = md5ff(a, b, c, d, x[i], 7, -680876936)
- d = md5ff(d, a, b, c, x[i + 1], 12, -389564586)
- c = md5ff(c, d, a, b, x[i + 2], 17, 606105819)
- b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330)
- a = md5ff(a, b, c, d, x[i + 4], 7, -176418897)
- d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426)
- c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341)
- b = md5ff(b, c, d, a, x[i + 7], 22, -45705983)
- a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416)
- d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417)
- c = md5ff(c, d, a, b, x[i + 10], 17, -42063)
- b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162)
- a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682)
- d = md5ff(d, a, b, c, x[i + 13], 12, -40341101)
- c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290)
- b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329)
-
- a = md5gg(a, b, c, d, x[i + 1], 5, -165796510)
- d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632)
- c = md5gg(c, d, a, b, x[i + 11], 14, 643717713)
- b = md5gg(b, c, d, a, x[i], 20, -373897302)
- a = md5gg(a, b, c, d, x[i + 5], 5, -701558691)
- d = md5gg(d, a, b, c, x[i + 10], 9, 38016083)
- c = md5gg(c, d, a, b, x[i + 15], 14, -660478335)
- b = md5gg(b, c, d, a, x[i + 4], 20, -405537848)
- a = md5gg(a, b, c, d, x[i + 9], 5, 568446438)
- d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690)
- c = md5gg(c, d, a, b, x[i + 3], 14, -187363961)
- b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501)
- a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467)
- d = md5gg(d, a, b, c, x[i + 2], 9, -51403784)
- c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473)
- b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734)
-
- a = md5hh(a, b, c, d, x[i + 5], 4, -378558)
- d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463)
- c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562)
- b = md5hh(b, c, d, a, x[i + 14], 23, -35309556)
- a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060)
- d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353)
- c = md5hh(c, d, a, b, x[i + 7], 16, -155497632)
- b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640)
- a = md5hh(a, b, c, d, x[i + 13], 4, 681279174)
- d = md5hh(d, a, b, c, x[i], 11, -358537222)
- c = md5hh(c, d, a, b, x[i + 3], 16, -722521979)
- b = md5hh(b, c, d, a, x[i + 6], 23, 76029189)
- a = md5hh(a, b, c, d, x[i + 9], 4, -640364487)
- d = md5hh(d, a, b, c, x[i + 12], 11, -421815835)
- c = md5hh(c, d, a, b, x[i + 15], 16, 530742520)
- b = md5hh(b, c, d, a, x[i + 2], 23, -995338651)
-
- a = md5ii(a, b, c, d, x[i], 6, -198630844)
- d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415)
- c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905)
- b = md5ii(b, c, d, a, x[i + 5], 21, -57434055)
- a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571)
- d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606)
- c = md5ii(c, d, a, b, x[i + 10], 15, -1051523)
- b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799)
- a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359)
- d = md5ii(d, a, b, c, x[i + 15], 10, -30611744)
- c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380)
- b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649)
- a = md5ii(a, b, c, d, x[i + 4], 6, -145523070)
- d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379)
- c = md5ii(c, d, a, b, x[i + 2], 15, 718787259)
- b = md5ii(b, c, d, a, x[i + 9], 21, -343485551)
-
- a = safeAdd(a, olda)
- b = safeAdd(b, oldb)
- c = safeAdd(c, oldc)
- d = safeAdd(d, oldd)
- }
- return [a, b, c, d]
- }
-
- /*
- * Convert an array of little-endian words to a string
- */
- function binl2rstr (input) {
- var i
- var output = ''
- var length32 = input.length * 32
- for (i = 0; i < length32; i += 8) {
- output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff)
- }
- return output
- }
-
- /*
- * Convert a raw string to an array of little-endian words
- * Characters >255 have their high-byte silently ignored.
- */
- function rstr2binl (input) {
- var i
- var output = []
- output[(input.length >> 2) - 1] = undefined
- for (i = 0; i < output.length; i += 1) {
- output[i] = 0
- }
- var length8 = input.length * 8
- for (i = 0; i < length8; i += 8) {
- output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32)
- }
- return output
- }
-
- /*
- * Calculate the MD5 of a raw string
- */
- function rstrMD5 (s) {
- return binl2rstr(binlMD5(rstr2binl(s), s.length * 8))
- }
-
- /*
- * Calculate the HMAC-MD5, of a key and some data (raw strings)
- */
- function rstrHMACMD5 (key, data) {
- var i
- var bkey = rstr2binl(key)
- var ipad = []
- var opad = []
- var hash
- ipad[15] = opad[15] = undefined
- if (bkey.length > 16) {
- bkey = binlMD5(bkey, key.length * 8)
- }
- for (i = 0; i < 16; i += 1) {
- ipad[i] = bkey[i] ^ 0x36363636
- opad[i] = bkey[i] ^ 0x5c5c5c5c
- }
- hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8)
- return binl2rstr(binlMD5(opad.concat(hash), 512 + 128))
- }
-
- /*
- * Convert a raw string to a hex string
- */
- function rstr2hex (input) {
- var hexTab = '0123456789abcdef'
- var output = ''
- var x
- var i
- for (i = 0; i < input.length; i += 1) {
- x = input.charCodeAt(i)
- output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f)
- }
- return output
- }
-
- /*
- * Encode a string as utf-8
- */
- function str2rstrUTF8 (input) {
- return unescape(encodeURIComponent(input))
- }
-
- /*
- * Take string arguments and return either raw or hex encoded strings
- */
- function rawMD5 (s) {
- return rstrMD5(str2rstrUTF8(s))
- }
- function hexMD5 (s) {
- return rstr2hex(rawMD5(s))
- }
- function rawHMACMD5 (k, d) {
- return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d))
- }
- function hexHMACMD5 (k, d) {
- return rstr2hex(rawHMACMD5(k, d))
- }
-
- function md5 (string, key, raw) {
- if (!key) {
- if (!raw) {
- return hexMD5(string)
- }
- return rawMD5(string)
- }
- if (!raw) {
- return hexHMACMD5(key, string)
- }
- return rawHMACMD5(key, string)
- }
-
- if (typeof define === 'function' && define.amd) {
- define(function () {
- return md5
- })
- } else if (typeof module === 'object' && module.exports) {
- module.exports = md5
- } else {
- $.md5 = md5
- }
-})(this);
-
-(function (scope) {
- 'use strict';
-
- var Fingerprint = function (options) {
- var nativeForEach, nativeMap;
- nativeForEach = Array.prototype.forEach;
- nativeMap = Array.prototype.map;
-
- this.each = function (obj, iterator, context) {
- if (obj === null) {
- return;
- }
- if (nativeForEach && obj.forEach === nativeForEach) {
- obj.forEach(iterator, context);
- } else if (obj.length === +obj.length) {
- for (var i = 0, l = obj.length; i < l; i++) {
- if (iterator.call(context, obj[i], i, obj) === {}) return;
- }
- } else {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- if (iterator.call(context, obj[key], key, obj) === {}) return;
- }
- }
- }
- };
-
- this.map = function(obj, iterator, context) {
- var results = [];
- // Not using strict equality so that this acts as a
- // shortcut to checking for `null` and `undefined`.
- if (obj == null) return results;
- if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
- this.each(obj, function(value, index, list) {
- results[results.length] = iterator.call(context, value, index, list);
- });
- return results;
- };
-
- if (typeof options == 'object'){
- this.hasher = options.hasher;
- this.screen_resolution = options.screen_resolution;
- this.canvas = options.canvas;
- this.ie_activex = options.ie_activex;
- } else if(typeof options == 'function'){
- this.hasher = options;
- }
- };
-
- Fingerprint.prototype = {
- get: function(){
- var keys = [];
- keys.push(navigator.userAgent);
- keys.push(navigator.language);
- keys.push(screen.colorDepth);
- if (this.screen_resolution) {
- var resolution = this.getScreenResolution();
- if (typeof resolution !== 'undefined'){ // headless browsers, such as phantomjs
- keys.push(this.getScreenResolution().join('x'));
- }
- }
- keys.push(new Date().getTimezoneOffset());
- keys.push(this.hasSessionStorage());
- keys.push(this.hasLocalStorage());
- keys.push(!!window.indexedDB);
- //body might not be defined at this point or removed programmatically
- if(document.body){
- keys.push(typeof(document.body.addBehavior));
- } else {
- keys.push(typeof undefined);
- }
- keys.push(typeof(window.openDatabase));
- keys.push(navigator.cpuClass);
- keys.push(navigator.platform);
- keys.push(navigator.doNotTrack);
- keys.push(this.getPluginsString());
- if(this.canvas && this.isCanvasSupported()){
- keys.push(this.getCanvasFingerprint());
- }
- if(this.hasher){
- return this.hasher(keys.join('###'), 31);
- } else {
- return this.murmurhash3_32_gc(keys.join('###'), 31);
- }
- },
-
- /**
- * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)
- *
- * @author Gary Court
- * @see http://github.com/garycourt/murmurhash-js
- * @author Austin Appleby
- * @see http://sites.google.com/site/murmurhash/
- *
- * @param {string} key ASCII only
- * @param {number} seed Positive integer only
- * @return {number} 32-bit positive integer hash
- */
-
- murmurhash3_32_gc: function(key, seed) {
- var remainder, bytes, h1, h1b, c1, c2, k1, i;
-
- remainder = key.length & 3; // key.length % 4
- bytes = key.length - remainder;
- h1 = seed;
- c1 = 0xcc9e2d51;
- c2 = 0x1b873593;
- i = 0;
-
- while (i < bytes) {
- k1 =
- ((key.charCodeAt(i) & 0xff)) |
- ((key.charCodeAt(++i) & 0xff) << 8) |
- ((key.charCodeAt(++i) & 0xff) << 16) |
- ((key.charCodeAt(++i) & 0xff) << 24);
- ++i;
-
- k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;
- k1 = (k1 << 15) | (k1 >>> 17);
- k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;
-
- h1 ^= k1;
- h1 = (h1 << 13) | (h1 >>> 19);
- h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;
- h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));
- }
-
- k1 = 0;
-
- switch (remainder) {
- case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
- case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
- case 1: k1 ^= (key.charCodeAt(i) & 0xff);
-
- k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
- k1 = (k1 << 15) | (k1 >>> 17);
- k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
- h1 ^= k1;
- }
-
- h1 ^= key.length;
-
- h1 ^= h1 >>> 16;
- h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
- h1 ^= h1 >>> 13;
- h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;
- h1 ^= h1 >>> 16;
-
- return h1 >>> 0;
- },
-
- // https://bugzilla.mozilla.org/show_bug.cgi?id=781447
- hasLocalStorage: function () {
- try{
- return !!scope.localStorage;
- } catch(e) {
- return true; // SecurityError when referencing it means it exists
- }
- },
-
- hasSessionStorage: function () {
- try{
- return !!scope.sessionStorage;
- } catch(e) {
- return true; // SecurityError when referencing it means it exists
- }
- },
-
- isCanvasSupported: function () {
- var elem = document.createElement('canvas');
- return !!(elem.getContext && elem.getContext('2d'));
- },
-
- isIE: function () {
- if(navigator.appName === 'Microsoft Internet Explorer') {
- return true;
- } else if(navigator.appName === 'Netscape' && /Trident/.test(navigator.userAgent)){// IE 11
- return true;
- }
- return false;
- },
-
- getPluginsString: function () {
- if(this.isIE()){
- return this.getIEPluginsString();
- } else {
- return this.getRegularPluginsString();
- }
- },
-
- getRegularPluginsString: function () {
- return this.map(navigator.plugins, function (p) {
- var mimeTypes = this.map(p, function(mt){
- return [mt.type, mt.suffixes].join('~');
- }).join(',');
- return [p.name, p.description, mimeTypes].join('::');
- }, this).join(';');
- },
-
- getIEPluginsString: function () {
- var names = ['ShockwaveFlash.ShockwaveFlash',//flash plugin
- 'AcroPDF.PDF', // Adobe PDF reader 7+
- 'PDF.PdfCtrl', // Adobe PDF reader 6 and earlier, brrr
- 'QuickTime.QuickTime', // QuickTime
- // 5 versions of real players
- 'rmocx.RealPlayer G2 Control',
- 'rmocx.RealPlayer G2 Control.1',
- 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
- 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)',
- 'RealPlayer',
- 'SWCtl.SWCtl', // ShockWave player
- 'WMPlayer.OCX', // Windows media player
- 'AgControl.AgControl', // Silverlight
- 'Skype.Detection'];
- if(this.ie_activex && scope.ActiveXObject){
- // starting to detect plugins in IE
- return this.map(names, function(name){
- try{
- new ActiveXObject(name);
- return name;
- } catch(e){
- return null;
- }
- }).join(';');
- } else {
- return ""; // behavior prior version 0.5.0, not breaking backwards compat.
- }
- },
-
- getScreenResolution: function () {
- return [screen.height, screen.width];
- },
-
- getCanvasFingerprint: function () {
- var canvas = document.createElement('canvas');
- var ctx = canvas.getContext('2d');
- // https://www.browserleaks.com/canvas#how-does-it-work
- var txt = 'http://valve.github.io';
- ctx.textBaseline = "top";
- ctx.font = "14px 'Arial'";
- ctx.textBaseline = "alphabetic";
- ctx.fillStyle = "#f60";
- ctx.fillRect(125,1,62,20);
- ctx.fillStyle = "#069";
- ctx.fillText(txt, 2, 15);
- ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
- ctx.fillText(txt, 4, 17);
- return canvas.toDataURL();
- }
- };
-
-
- if (typeof module === 'object' && typeof exports === 'object') {
- module.exports = Fingerprint;
- }
- scope.Fingerprint = Fingerprint;
-})(window);
-
-var fp=md5(new Fingerprint({canvas: true}+_fp(fp_arr[0])).get()).slice(0,8);
-
-function _fp(txt)
-{
- var canvas = document.createElement('canvas');
- var ctx = canvas.getContext('2d');
- if(!txt) txt = 'https://security.yimian.xyz/';
- ctx.textBaseline = "top";
- ctx.font = "15px 'Arial'";
- ctx.textBaseline = "yimian";
- ctx.fillStyle = "#f66";
- ctx.fillRect(125, 1, 52, 20);
- ctx.fillStyle = "#039";
- ctx.fillText(txt, 2, 15);
- ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
- ctx.fillText(txt, 4, 17);
- var b64 = canvas.toDataURL();
- b64 = b64.replace("data:image/png;base64,", "");
- var bin = atob(b64).slice(-16, -12);
- var i, l, o = '',n;
- bin += '';
- for (i = 0, l = bin.length; i < l; i++) {
- n = bin.charCodeAt(i).toString(16);
- o += n.length < 2 ? '0' + n : n
- }
- console.log('\n' + ' %c fp fingerprint generator %c https://github.com/hhCandy/fp ' + '\n', 'color: #00FFFF; background: #030307; padding:5px 0;', 'background: #4682B4; padding:5px 0;');
- return o;
-};
diff --git a/fp.min.js b/fp.min.js
new file mode 100644
index 0000000..e326860
--- /dev/null
+++ b/fp.min.js
@@ -0,0 +1 @@
+(function(name,context,definition){if(typeof module!=="undefined"&&module.exports){module.exports=definition()}else if(typeof define==="function"&&define.amd){define(definition)}else{context[name]=definition()}})("fp",this,function(){"use strict";var Fingerprint=function(options){var nativeForEach,nativeMap;nativeForEach=Array.prototype.forEach;nativeMap=Array.prototype.map;this.each=function(obj,iterator,context){if(obj===null){return}if(nativeForEach&&obj.forEach===nativeForEach){obj.forEach(iterator,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i>>16)*c1&65535)<<16)&4294967295;k1=k1<<15|k1>>>17;k1=(k1&65535)*c2+(((k1>>>16)*c2&65535)<<16)&4294967295;h1^=k1;h1=h1<<13|h1>>>19;h1b=(h1&65535)*5+(((h1>>>16)*5&65535)<<16)&4294967295;h1=(h1b&65535)+27492+(((h1b>>>16)+58964&65535)<<16)}k1=0;switch(remainder){case 3:k1^=(key.charCodeAt(i+2)&255)<<16;case 2:k1^=(key.charCodeAt(i+1)&255)<<8;case 1:k1^=key.charCodeAt(i)&255;k1=(k1&65535)*c1+(((k1>>>16)*c1&65535)<<16)&4294967295;k1=k1<<15|k1>>>17;k1=(k1&65535)*c2+(((k1>>>16)*c2&65535)<<16)&4294967295;h1^=k1}h1^=key.length;h1^=h1>>>16;h1=(h1&65535)*2246822507+(((h1>>>16)*2246822507&65535)<<16)&4294967295;h1^=h1>>>13;h1=(h1&65535)*3534925365+(((h1>>>16)*3534925365&65535)<<16)&4294967295;h1^=h1>>>16;var r=["1","2","3","4","5","6","7","8","9","0","a","b","c","d","e","f","g","h","i","g","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];return h1,r[h1&31+2]+r[(h1&31<<6)>>>6]+r[(h1&31<<13)>>>13+4]+r[(h1&31<<20)>>>20]+r[(h1&31<<27)>>>27+1]+r[(h1&31<<35)>>>35]+r[(h1&31<<42)>>>42+2]+r[(h1&31<<51)>>>51+3]},hasLocalStorage:function(){try{return!!window.localStorage}catch(e){return true}},hasSessionStorage:function(){try{return!!window.sessionStorage}catch(e){return true}},hasIndexDb:function(){try{return!!window.indexedDB}catch(e){return true}},isCanvasSupported:function(){var elem=document.createElement("canvas");return!!(elem.getContext&&elem.getContext("2d"))},isIE:function(){if(navigator.appName==="Microsoft Internet Explorer"){return true}else if(navigator.appName==="Netscape"&&/Trident/.test(navigator.userAgent)){return true}return false},getPluginsString:function(){if(this.isIE()&&this.ie_activex){return this.getIEPluginsString()}else{return this.getRegularPluginsString()}},getRegularPluginsString:function(){return this.map(navigator.plugins,function(p){var mimeTypes=this.map(p,function(mt){return[mt.type,mt.suffixes].join("~")}).join(",");return[p.name,p.description,mimeTypes].join("::")},this).join(";")},getIEPluginsString:function(){if(window.ActiveXObject){var names=["ShockwaveFlash.ShockwaveFlash","AcroPDF.PDF","PDF.PdfCtrl","QuickTime.QuickTime","rmocx.RealPlayer G2 Control","rmocx.RealPlayer G2 Control.1","RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)","RealVideo.RealVideo(tm) ActiveX Control (32-bit)","RealPlayer","SWCtl.SWCtl","WMPlayer.OCX","AgControl.AgControl","Skype.Detection"];return this.map(names,function(name){try{new ActiveXObject(name);return name}catch(e){return null}}).join(";")}else{return""}},getScreenResolution:function(){var resolution;if(this.screen_orientation){resolution=screen.height>screen.width?[screen.height,screen.width]:[screen.width,screen.height]}else{resolution=[screen.height,screen.width]}return resolution},getCanvasFingerprint:function(){var canvas=document.createElement("canvas");var ctx=canvas.getContext("2d");var txt="https://fp.yimian.xyz";ctx.textBaseline="top";ctx.font="14px 'Arial'";ctx.textBaseline="alphabetic";ctx.fillStyle="#f60";ctx.fillRect(125,1,62,20);ctx.fillStyle="#069";ctx.fillText(txt,2,15);ctx.fillStyle="rgba(102, 204, 0, 0.7)";ctx.fillText(txt,4,17);return canvas.toDataURL()}};return Fingerprint});var fp=(new fp).get();
\ No newline at end of file
diff --git a/fp.min.js.map b/fp.min.js.map
new file mode 100644
index 0000000..779c05f
--- /dev/null
+++ b/fp.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["test-fp.js"],"names":["name","context","definition","module","exports","define","amd","this","Fingerprint","options","nativeForEach","nativeMap","Array","prototype","forEach","map","each","obj","iterator","length","i","l","call","key","hasOwnProperty","results","value","index","list","screen_resolution","screen_orientation","ie_activex","get","keys","push","navigator","userAgent","language","screen","colorDepth","resolution","getScreenResolution","join","Date","getTimezoneOffset","hasSessionStorage","hasLocalStorage","hasIndexDb","document","body","undefined","window","cpuClass","platform","doNotTrack","getPluginsString","isCanvasSupported","getCanvasFingerprint","murmurhash3_32_gc","seed","remainder","bytes","h1","h1b","c1","c2","k1","charCodeAt","r","localStorage","e","sessionStorage","indexedDB","elem","createElement","getContext","isIE","appName","test","getIEPluginsString","getRegularPluginsString","plugins","p","mimeTypes","mt","type","suffixes","description","ActiveXObject","names","height","width","canvas","ctx","txt","textBaseline","font","fillStyle","fillRect","fillText","toDataURL","fp"],"mappings":"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"}
\ No newline at end of file
diff --git a/index.html b/index.html
index 018767f..3b86cc2 100644
--- a/index.html
+++ b/index.html
@@ -1,2 +1,2 @@
-
+
\ No newline at end of file
diff --git a/src/client/cookie.js b/src/client/cookie.js
new file mode 100644
index 0000000..29cfdb9
--- /dev/null
+++ b/src/client/cookie.js
@@ -0,0 +1,29 @@
+var cookie = {
+ set: function(name, value) {
+ var Days = 30;
+ var exp = new Date();
+ exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
+ document.cookie = name + '=' + escape(value) + ';expires=' + exp.toGMTString() + ";path=/";
+ },
+ get: function(name) {
+ var arr, reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');
+ if(arr = document.cookie.match(reg)) {
+ return unescape(arr[2]);
+ } else {
+ return null;
+ }
+ },
+ del: function(name) {
+ var exp = new Date();
+ exp.setTime(exp.getTime() - 1);
+ var arr, reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');
+ if(arr = document.cookie.match(reg)) {
+ var cval = unescape(arr[2]);
+ } else {
+ var cval = null;
+ }
+ if(cval != null) {
+ document.cookie = name + '=' + cval + ';expires=' + exp.toGMTString();
+ }
+ }
+ };
\ No newline at end of file
diff --git a/src/client/demo.html b/src/client/demo.html
new file mode 100644
index 0000000..64fb493
--- /dev/null
+++ b/src/client/demo.html
@@ -0,0 +1,4 @@
+
+
+
+Go to fp's Web Page!
\ No newline at end of file
diff --git a/src/client/fp.js b/src/client/fp.js
new file mode 100644
index 0000000..ea7738a
--- /dev/null
+++ b/src/client/fp.js
@@ -0,0 +1,334 @@
+/**
+ * fp.js
+ *
+ * @category fp
+ * @package fp.js
+ * @copyright IoTcat(https://iotcat.me) developed from Valve/fingerprintjs(https://github.com/Valve/fingerprintjs)
+ * @license MIT
+ * @version 0.2.1
+ */
+;(function (name, context, definition) {
+ if (typeof module !== 'undefined' && module.exports) { module.exports = definition(); }
+ else if (typeof define === 'function' && define.amd) { define(definition); }
+ else { context[name] = definition(); }
+})('fp', this, function () {
+ 'use strict';
+
+ var Fingerprint = function (options) {
+ var nativeForEach, nativeMap;
+ nativeForEach = Array.prototype.forEach;
+ nativeMap = Array.prototype.map;
+
+ this.each = function (obj, iterator, context) {
+ if (obj === null) {
+ return;
+ }
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (iterator.call(context, obj[i], i, obj) === {}) return;
+ }
+ } else {
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ if (iterator.call(context, obj[key], key, obj) === {}) return;
+ }
+ }
+ }
+ };
+
+ this.map = function(obj, iterator, context) {
+ var results = [];
+ // Not using strict equality so that this acts as a
+ // shortcut to checking for `null` and `undefined`.
+ if (obj == null) return results;
+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+ this.each(obj, function(value, index, list) {
+ results[results.length] = iterator.call(context, value, index, list);
+ });
+ return results;
+ };
+
+ this.screen_resolution = true;
+ this.screen_orientation = true;
+ this.ie_activex = true;
+
+ };
+
+ Fingerprint.prototype = {
+
+ get_fp: function(){
+ var keys = [];
+ keys.push(navigator.userAgent);
+ keys.push(navigator.language);
+ keys.push(screen.colorDepth);
+ if (this.screen_resolution) {
+ var resolution = this.getScreenResolution();
+ if (typeof resolution !== 'undefined'){ // headless browsers, such as phantomjs
+ keys.push(resolution.join('x'));
+ }
+ }
+ keys.push(new Date().getTimezoneOffset());
+ keys.push(this.hasSessionStorage());
+ keys.push(this.hasLocalStorage());
+ keys.push(this.hasIndexDb());
+ //body might not be defined at this point or removed programmatically
+ if(document.body){
+ keys.push(typeof(document.body.addBehavior));
+ } else {
+ keys.push(typeof undefined);
+ }
+ keys.push(typeof(window.openDatabase));
+ keys.push(navigator.cpuClass);
+ keys.push(navigator.platform);
+ keys.push(navigator.doNotTrack);
+ keys.push(this.getPluginsString());
+ if(this.isCanvasSupported()){
+ keys.push(this.getCanvasFingerprint());
+ }
+
+ return this.murmurhash3_32_gc(keys.join('###'), 31);
+ },
+
+ murmurhash3_32_gc: function(key, seed) {
+ var remainder, bytes, h1, h1b, c1, c2, k1, i;
+
+ remainder = key.length & 3; // key.length % 4
+ bytes = key.length - remainder;
+ h1 = seed;
+ c1 = 0xcc9e2d51;
+ c2 = 0x1b873593;
+ i = 0;
+
+ while (i < bytes) {
+ k1 =
+ ((key.charCodeAt(i) & 0xff)) |
+ ((key.charCodeAt(++i) & 0xff) << 8) |
+ ((key.charCodeAt(++i) & 0xff) << 16) |
+ ((key.charCodeAt(++i) & 0xff) << 24);
+ ++i;
+
+ k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;
+ k1 = (k1 << 15) | (k1 >>> 17);
+ k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;
+
+ h1 ^= k1;
+ h1 = (h1 << 13) | (h1 >>> 19);
+ h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;
+ h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));
+ }
+
+ k1 = 0;
+
+ switch (remainder) {
+ case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
+ case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
+ case 1: k1 ^= (key.charCodeAt(i) & 0xff);
+
+ k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
+ k1 = (k1 << 15) | (k1 >>> 17);
+ k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
+ h1 ^= k1;
+ }
+
+ h1 ^= key.length;
+
+ h1 ^= h1 >>> 16;
+ h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
+ h1 ^= h1 >>> 13;
+ h1 = ((((h1 & 0xffff) * 0xd2b2ae35) + ((((h1 >>> 16) * 0xd2b2ae35) & 0xffff) << 16))) & 0xffffffff;
+ h1 ^= h1 >>> 16;
+ //transfer result to 8 words
+ var r = ['1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
+
+ return h1, r[h1 & 31 + 2] + r[(h1 & (31 << 6))>>>6] + r[(h1 & (31 << 13)) >>> 13 + 4] + r[(h1 & (31 << 20)) >>> 20]+ r[(h1 & (31 << 27)) >>> 27 + 1]+ r[(h1 & (31 << 35)) >>> 35]+ r[(h1 & (31 << 42)) >>> 42 +2]+ r[(h1 & (31 << 51)) >>> 51 + 3];
+ },
+
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=781447
+ hasLocalStorage: function () {
+ try{
+ return !!window.localStorage;
+ } catch(e) {
+ return true; // SecurityError when referencing it means it exists
+ }
+ },
+
+ hasSessionStorage: function () {
+ try{
+ return !!window.sessionStorage;
+ } catch(e) {
+ return true; // SecurityError when referencing it means it exists
+ }
+ },
+
+ hasIndexDb: function () {
+ try{
+ return !!window.indexedDB;
+ } catch(e) {
+ return true; // SecurityError when referencing it means it exists
+ }
+ },
+
+ isCanvasSupported: function () {
+ var elem = document.createElement('canvas');
+ return !!(elem.getContext && elem.getContext('2d'));
+ },
+
+ isIE: function () {
+ if(navigator.appName === 'Microsoft Internet Explorer') {
+ return true;
+ } else if(navigator.appName === 'Netscape' && /Trident/.test(navigator.userAgent)){// IE 11
+ return true;
+ }
+ return false;
+ },
+
+ getPluginsString: function () {
+ if(this.isIE() && this.ie_activex){
+ return this.getIEPluginsString();
+ } else {
+ return this.getRegularPluginsString();
+ }
+ },
+
+ getRegularPluginsString: function () {
+ return this.map(navigator.plugins, function (p) {
+ var mimeTypes = this.map(p, function(mt){
+ return [mt.type, mt.suffixes].join('~');
+ }).join(',');
+ return [p.name, p.description, mimeTypes].join('::');
+ }, this).join(';');
+ },
+
+ getIEPluginsString: function () {
+ if(window.ActiveXObject){
+ var names = ['ShockwaveFlash.ShockwaveFlash',//flash plugin
+ 'AcroPDF.PDF', // Adobe PDF reader 7+
+ 'PDF.PdfCtrl', // Adobe PDF reader 6 and earlier, brrr
+ 'QuickTime.QuickTime', // QuickTime
+ // 5 versions of real players
+ 'rmocx.RealPlayer G2 Control',
+ 'rmocx.RealPlayer G2 Control.1',
+ 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
+ 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)',
+ 'RealPlayer',
+ 'SWCtl.SWCtl', // ShockWave player
+ 'WMPlayer.OCX', // Windows media player
+ 'AgControl.AgControl', // Silverlight
+ 'Skype.Detection'];
+
+ // starting to detect plugins in IE
+ return this.map(names, function(name){
+ try{
+ new ActiveXObject(name);
+ return name;
+ } catch(e){
+ return null;
+ }
+ }).join(';');
+ } else {
+ return ""; // behavior prior version 0.5.0, not breaking backwards compat.
+ }
+ },
+
+ getScreenResolution: function () {
+ var resolution;
+ if(this.screen_orientation){
+ resolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height];
+ }else{
+ resolution = [screen.height, screen.width];
+ }
+ return resolution;
+ },
+
+ getCanvasFingerprint: function () {
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+ var txt = 'https://fp.yimian.xyz';
+ ctx.textBaseline = "top";
+ ctx.font = "14px 'Arial'";
+ ctx.textBaseline = "alphabetic";
+ ctx.fillStyle = "#f60";
+ ctx.fillRect(125,1,62,20);
+ ctx.fillStyle = "#069";
+ ctx.fillText(txt, 2, 15);
+ ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
+ ctx.fillText(txt, 4, 17);
+ return canvas.toDataURL();
+ }
+ };
+
+
+ return Fingerprint;
+
+});
+
+
+var fp = new fp().get_fp();
+
+var fp_socket = {
+
+ fp: fp,
+ _cookie: {},
+ g_cookie: {}
+};
+
+
+var cookie = {
+
+ set: function(name, value, expire) {
+
+ fp_socket._cookie[name] = {
+ val: value,
+ exp: expire,
+ stt: Date.parse(new Date())/1000
+ };
+ $.post("https://cn.yimian.xyz/etc/fp/src/server/fp.php",fp_socket, function(msg){
+
+ var obj = eval('(' + msg + ')');
+ fp_socket._cookie = obj._cookie;
+ fp_socket.g_cookie = obj.g_cookie;
+ });
+ },
+ g_set: function(name, value, expire) {
+
+ fp_socket.g_cookie[name] = {
+ val: value,
+ exp: expire,
+ stt: Date.parse(new Date())/1000
+ };
+ $.post("https://cn.yimian.xyz/etc/fp/src/server/fp.php",fp_socket, function(msg){
+
+ var obj = eval('(' + msg + ')');
+ fp_socket._cookie = obj._cookie;
+ fp_socket.g_cookie = obj.g_cookie;
+ });
+ },
+ get: function(name) {
+
+ if(fp_socket._cookie[name] != undefined){
+ if(fp_socket._cookie[name].stt + fp_socket._cookie[name].exp > Date.parse(new Date())/1000){
+ return fp_socket._cookie[name].val;
+ }else{
+ this.del(name);
+ }
+ }else if(fp_socket.g_cookie[name] != undefined){
+ if(fp_socket.g_cookie[name].stt + fp_socket.g_cookie[name].exp > Date.parse(new Date())/1000){
+ return fp_socket.g_cookie[name].val;
+ }else{
+ this.del(name);
+ }
+ }
+ return null;
+ },
+ del: function(name) {
+
+ Reflect.deleteProperty(fp_socket._cookie, name);
+ },
+ g_del: function(name) {
+
+ Reflect.deleteProperty(fp_socket.g_cookie, name);
+ }
+
+}
diff --git a/src/server/fp.php b/src/server/fp.php
new file mode 100644
index 0000000..4b2d53e
--- /dev/null
+++ b/src/server/fp.php
@@ -0,0 +1,128 @@
+push();
+echo $obj->get();
+
+
+//echo json_encode(merge_cookies($a, $b));
+
+
+
+die();
+
+
+
+class fp{
+
+ public function __construct($_fp_cookie, $dir = "__cookie__")
+ {
+ //$res = json_decode($_fp_cookie);
+ $this->_fp = $_REQUEST['fp'];
+ $this->_dir = $dir;
+ $this->_cookie = $_REQUEST['_cookie'];
+ $this->g_cookie = $_REQUEST['g_cookie'];
+ }
+
+ private $_fp;
+ private $_dir;
+ private $_cookie;
+ private $g_cookie;
+
+ public function push(){
+ $this->_cookie = $this->merge_cookies($this->get_cookie(), $this->_cookie);
+ $this->g_cookie = $this->merge_cookies($this->get_g_cookie(), $this->g_cookie);
+
+ $f = fopen($this->_dir.'/'.($this->get_cookie_fname()), "w");
+ fwrite($f, json_encode($this->_cookie));
+ fclose($f);
+ $f = fopen($this->_dir.'/'.($this->get_g_cookie_fname()), "w");
+ fwrite($f, json_encode($this->g_cookie));
+ fclose($f);
+ }
+
+ public function get(){
+
+ $i = array();
+ $i['_cookie'] = $this->get_cookie();
+ $i['g_cookie'] = $this->get_g_cookie();
+ return json_encode($i);
+ }
+
+ public function get_g_cookie(){
+ return (array)json_decode(file_get_contents($this->_dir.'/'.($this->get_g_cookie_fname())));
+ }
+
+ public function get_cookie(){
+ return (array)json_decode(file_get_contents($this->_dir.'/'.($this->get_cookie_fname())));
+ }
+
+ public function get_cookie_fname(){
+ return md5(($this->_fp)."#".($this->get_from_domain())).".fp";
+ }
+
+ public function get_g_cookie_fname(){
+ return md5(($this->_fp)."#"."g").".fp";
+ }
+
+
+ /** get from address **/
+ private function get_from(){
+
+ if($_SERVER['HTTP_REFERER']) return $_SERVER['HTTP_REFERER'];
+ return "https://fp.yimian.xyz";
+ die(json_encode(array("state" => 0, "message" => "No HTTP_REFERER in HTTP header!!")));
+ }
+
+ private function get_from_domain(){
+ $str = str_replace("http://","",$this->get_from());
+ $str = str_replace("https://","",$str);
+ $strdomain = explode("/",$str);
+ return $strdomain[0];
+ }
+
+
+ private function md_dir(){
+ if (!file_exists($this->_dir)){
+ mkdir($this->_dir,0777,true);
+ }
+ }
+
+ private function merge_cookies($a, $b){
+
+ $a_keys = array_keys($a);
+ $b_keys = array_keys($b);
+
+ foreach($a_keys as $t_a){
+
+ $cnt = 0;
+ foreach($b_keys as $t_b){
+
+ if($t_b == $t_a){
+
+ $c_a = (array)$a[$t_b];
+ $c_b = (array)$b[$t_b];
+
+ if($c_a['stt'] > $c_b['stt']){
+
+ $b[$t_b] = $a[$t_b];
+ }
+
+ }else{
+ $cnt++;
+ }
+ }
+ if($cnt == count($b_keys)){
+ $b[$t_a] = $a[$t_a];
+ }
+ }
+
+ return $b;
+ }
+}
\ No newline at end of file