UNPKG

browser-canvas-fingerprinting

Version:

A simple canvas fingerprinting implementation in browser with specific information used to generate fingerprint

3 lines (2 loc) 13.4 kB
async function b(e){return Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256",e))).map(r=>r.toString(16).padStart(2,"0")).join("")}async function g(e){return await b(new TextEncoder().encode(e))}async function h(e){return await b(await e.arrayBuffer())}function L(){let e=["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Impact","Times New Roman","Trebuchet MS","Verdana","Microsoft YaHei","SimSun","SimHei","KaiTi","FangSong","NSimSun","Hiragino Sans GB","PingFang SC","STHeiti","WenQuanYi Micro Hei","DejaVu Sans","Liberation Sans","Ubuntu","Helvetica"],r=[],a=(new OffscreenCanvas(100,100)||document.createElement("canvas")).getContext("2d"),i="mmmmmmmmmmlli";a.font="72px monospace";let n=a.measureText(i).width;return e.forEach(f=>{a.font=`72px "${f}", monospace`,a.measureText(i).width!==n&&r.push(f)}),r}function v(){return L()}function M(e){return[/intel/i,/nvidia/i,/amd/i,/google/i,/apple/i,/microsoft/i,/mesa/i,/llvmpipe/i,/vmware/i,/qualcomm/i,/arm/i,/ati technologies/i,/d3d/i].some(t=>t.test(e))?!1:!!/^[A-Za-z0-9\-]{8}$/.test(e)}function F(){try{let r=(new OffscreenCanvas(100,100)||document.createElement("canvas")).getContext("webgl");if(!r)return{vendor:"N/A",renderer:"N/A"};let t=r.getExtension("WEBGL_debug_renderer_info");if(t){let a={vendor:r.getParameter(t.UNMASKED_VENDOR_WEBGL)||"N/A",renderer:r.getParameter(t.UNMASKED_RENDERER_WEBGL)||"N/A"};return M(a.vendor)||M(a.renderer)?{vendor:"Fucked by extension",renderer:"Fucked by extension"}:a}}catch{}return{vendor:"N/A",renderer:"N/A"}}async function D(){try{let i=function(d,A,w){let c=d.createShader(A);return d.shaderSource(c,w),d.compileShader(c),d.getShaderParameter(c,d.COMPILE_STATUS)?c:(console.error("Shader compile error:",d.getShaderInfoLog(c)),d.deleteShader(c),null)},e=new OffscreenCanvas(512,512)||document.createElement("canvas");e.width=512,e.height=512;let r=e.getContext("webgl");if(!r)return"Not Supported";let t="attribute vec4 aPosition;void main() {gl_Position = aPosition;}",a="void main() {gl_FragColor = vec4(1.0, 0.5, 0.2, 1.0); }",n=i(r,r.VERTEX_SHADER,t),f=i(r,r.FRAGMENT_SHADER,a),u=r.createProgram();if(r.attachShader(u,n),r.attachShader(u,f),r.linkProgram(u),!r.getProgramParameter(u,r.LINK_STATUS))return console.error("Program link error:",r.getProgramInfoLog(u)),null;r.useProgram(u);let o=[-.5,-.5,.5,-.5,0,.5],l=r.createBuffer();r.bindBuffer(r.ARRAY_BUFFER,l),r.bufferData(r.ARRAY_BUFFER,new Float32Array(o),r.STATIC_DRAW);let s=r.getAttribLocation(u,"aPosition");return r.enableVertexAttribArray(s),r.vertexAttribPointer(s,2,r.FLOAT,!1,0,0),r.clearColor(.1,.2,.3,1),r.clear(r.COLOR_BUFFER_BIT),r.drawArrays(r.TRIANGLES,0,3),e.convertToBlob?await h(await e.convertToBlob()):await g(e.toDataURL("image/png"))}catch(e){return"Failed to generate: "+String(e)}}function T(e){if(!e)return 0;let r=new WeakSet;function t(a){if(a===null||typeof a!="object"||r.has(a))return 0;r.add(a);let i=Reflect.ownKeys(a).length,n=Object.getPrototypeOf(a);return n!==null&&(i+=t(n)),i}return t(e)}function U(e){if(e<=0||!Number.isInteger(e))throw new Error("bits must be a positive integer");let r=Math.ceil(e/8),t=new Uint8Array(r);crypto.getRandomValues(t);let a=0n;for(let i=0;i<r;i++)a=a<<8n|BigInt(t[i]);return a&(1n<<BigInt(e))-1n}async function y(){if(typeof window>"u")return!1;if(!globalThis.Worker)return!0;let e=document.createElement("canvas");e.width=1920,e.height=1080,document.body.append(e);let r=e.getContext("2d");if(r.fillStyle="red",r.fillRect(0,0,100,100),await new Promise(t=>setTimeout(t,10)),e.toDataURL()!==e.toDataURL())return e.remove(),!0;try{r.getImageData()}catch(t){e.remove();let a=t.stack;if(a&&!/chrome-extension/i.test(a))return!1}return e.remove(),!0}async function p(){function e(o,l=!1){try{return o()}catch(s){return l?s.stack:String(s)}}async function r(o,l=!1){try{return await o()}catch(s){return l?s.stack:String(s)}}function t(){let o=Math.random().toString().substring(2);return e(()=>new Function("a"+o)()).replace(o,"<R>")}function a(){let o=Math.random().toString().substring(2);return e(()=>globalThis[o]["//"].b).replace(o,"<R>")}function i(){let o=globalThis.navigator.hardwareConcurrency;return!o||o%2?"N/A":o}let n=await y(),{vendor:f,renderer:u}=F();return["Emojis: \u{1F601}\u{1F602}\u{1F603}\u{1F604}\u{1F60C}\u{1F60F}\u{1F612}\u{1F621}\u{1F631}\u{1F628}","Special chars (Unicode): \u2060\u200B\u25CF\u25CB\u25D0\u25D1\u25D2\u25D3\u2605\u2606\u2724\u2726\u2736\u2737\u272A\u272B\u272F\u2730\u2742\u25C6\u25C8\u25B6\u25C0\u25B2\u25BC\u25BA\u25C4\u27A4\u27A5\u27A1\u27A2\u2740\u273F\u2741\u273E\u2668\u266A\u266B\u2669\u2704\u2702\u2701\u2706\u2709\u2756\u2726\u2727\u221E\u2763\u2765\u2719\u271A\u271C\u271B\u2020\u2021","Zalgo: \u0334\u0322\u031B\u031B\u0317\u0318Z\u0337\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033F\u035D\u035D\u030F\u033F\u030F\u035D\u033F\u035D\u030F\u033F\u035Da\u0335\u031B\u030C\u0344\u035D\u033F\u030F\u035D\u033F\u035D\u030F\u033F\u035Dl\u0336\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033Fg\u0337\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033Fo\u0334\u0322\u031B\u031B\u0317\u0318 \u0334\u0322\u031B\u031B\u0317\u0318T\u0337\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033Fe\u0335\u031B\u030C\u0344\u035D\u033F\u030F\u035D\u033F\u035D\u030F\u033F\u035Dx\u0336\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033Ft\u0337\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033F",`User-Agent: ${globalThis.navigator.userAgent}`,`Platform: ${globalThis.navigator.platform}`,`Languages: ${globalThis.navigator.languages}`,`Cookies enabled: ${globalThis.navigator.cookieEnabled}`,`Navigator properties count: ${T(globalThis.navigator)}`,`Timezone: ${e(()=>globalThis.Intl.DateTimeFormat().resolvedOptions().timeZone)}`,`Fonts: ${v()}`,`Hardware Concurrency: ${n?"Ignored due to extension activity":i()}`,`Plugins: ${navigator.plugins?Array.from(navigator.plugins).map(o=>o.name).join(", "):"unknown"}`,`Screen: ${screen.width}x${screen.height}, Depth: ${screen.colorDepth}bit`,`Available Screen: ${screen.availWidth}x${screen.availHeight}`,`Max Touch Points: ${n?"Ignored due to extension activity":globalThis.navigator.maxTouchPoints}`,`WebGL Vendor: ${f}`,`WebGL Renderer: ${u}`,`WebGL Fingerprint: ${await D()}`,`Support navigation API: ${globalThis.navigation}`,`Support WebXR API: ${globalThis.navigator.xr}`,`Support WebGPU API: ${globalThis.navigator.gpu}`,`Browser error message: ${a()};${t()};${e(()=>customElements.define())};${e(()=>new Function("';|+_<"))};${await r(()=>crypto.subtle.encrypt())};${e(()=>structuredClone(globalThis))}`]}function C(){return[["linear",0,0,1,1,[[0,"#ff6b6b"],[.5,"#4ecdc4"],[1,"#45b7d1"]]],["linear",0,0,0,1,[[0,"#a8e6cf"],[.5,"#dcedc1"],[1,"#ff63b6"]]],["linear",0,0,1,0,[[0,"#74ebd5"],[1,"#9face6"]]],["radial",.5,.5,0,.5,.5,1,[[0,"#ff9a9e"],[1,"#fecfef"]]],["radial",.7,.3,0,.3,.7,1,[[0,"#4facfe"],[1,"#00f2fe"]]],["linear",0,0,1,1,[[0,"#ff0080"],[.5,"#ff8c00"],[1,"#40e0d0"]]],["linear",1,0,0,1,[[0,"#00ff87"],[.5,"#60efff"],[1,"#0061ff"]]],["radial",.5,.5,0,.5,.5,1,[[0,"#ff00cc"],[1,"#333399"]]],["linear",0,0,1,1,[[0,"#8e9eab"],[.3,"#eef2f3"],[.7,"#eef2f3"],[1,"#8eae3b"]]],["linear",.2,.2,.8,.8,[[0,"#4da0b0"],[.5,"#d39d38"],[1,"#4da0b0"]]],["linear",0,0,1,0,[[0,"rgba(255,0,150,0.8)"],[.5,"rgba(0,204,255,0.9)"],[1,"rgba(0,255,100,0.7)"]]],["linear",0,1,1,0,[[0,"#ffecd2"],[.5,"#fcb69f"],[1,"#a1c4fd"]]],["linear",1,0,0,1,[[0,"#667eea"],[1,"#764ba2"]]],["linear",0,0,1,0,[[0,"#ff0000"],[.16,"#ff9900"],[.33,"#ffff00"],[.5,"#00ff00"],[.66,"#00ffff"],[.83,"#0000ff"],[1,"#ff00ff"]]],["linear",0,0,1,1,[[0,"#d9afd9"],[.5,"#97d9e1"],[1,"#b5fffc"]]],["radial",.5,.5,0,.5,.5,.8,[[0,"#fad0c4"],[1,"#ffd1ff"]]],["linear",0,0,1,1,[[0,"#0c0c0c"],[.3,"#2d3436"],[1,"#636e72"]]],["radial",.5,.5,0,.5,.5,1,[[0,"#485563"],[1,"#29323c"]]],["linear",.3,.3,.7,.7,[[0,"#fa709a"],[1,"#fee140"]]],["linear",0,.5,1,.5,[[0,"#43e97b"],[.5,"#38f9d7"],[1,"#43e97b"]]]]}async function P(e,r){for(let n=0;n<200;n++){let f=n*123.456%r.width,u=n*67.89%r.height,o=n%3+1,l=150+n%105;e.fillStyle=`rgb(${l}, ${l}, 255)`,e.beginPath(),e.arc(f,u,o,0,3.14159*2),e.fill()}e.save(),e.translate(120,100),e.rotate(3.14159/6);let t=e.createLinearGradient(-75,-50,75,50);t.addColorStop(0,"#e0e0e0"),t.addColorStop(.3,"#ffffff"),t.addColorStop(.5,"#a0a0a0"),t.addColorStop(.7,"#c0c0c0"),t.addColorStop(1,"#808080"),e.fillStyle=t,e.shadowColor="rgba(0, 0, 0, 0.5)",e.shadowBlur=15,e.shadowOffsetX=5,e.shadowOffsetY=5,e.fillRect(-75,-50,150,100),e.strokeStyle="rgba(255, 255, 255, 0.8)",e.lineWidth=2,e.beginPath(),e.moveTo(-70,-45),e.lineTo(-20,-45),e.lineTo(-25,-40),e.stroke(),e.restore(),e.save(),e.shadowColor="#0ff",e.shadowBlur=30,e.fillStyle="#00ffff",e.beginPath(),e.arc(300,100,40,0,3.14159*2),e.fill(),e.shadowBlur=0,e.fillStyle="#ffffff",e.beginPath(),e.arc(300,100,25,0,3.14159*2),e.fill(),e.restore(),e.save();let a=e.createLinearGradient(250,50,350,150);a.addColorStop(0,"#ff0000"),a.addColorStop(.2,"#ffff00"),a.addColorStop(.4,"#00ff00"),a.addColorStop(.6,"#00ffff"),a.addColorStop(.8,"#0000ff"),a.addColorStop(1,"#ff00ff"),e.fillStyle=a,e.shadowColor="rgba(255, 0, 255, 0.5)",e.shadowBlur=20,e.beginPath(),e.moveTo(400,50),e.lineTo(450,150),e.lineTo(350,150),e.closePath(),e.fill(),e.restore(),e.save();let i=e.createRadialGradient(550,100,10,550,100,60);i.addColorStop(0,"#ff6b6b"),i.addColorStop(.5,"#4ecdc4"),i.addColorStop(1,"#45b7d1"),e.fillStyle=i,e.shadowColor="rgba(78, 205, 196, 0.5)",e.shadowBlur=25,e.beginPath(),e.arc(550,100,50,0,3.14159*2),e.fill(),e.restore(),e.save(),e.translate(200,250),e.fillStyle="rgba(255, 105, 180, 0.8)",e.shadowColor="rgba(255, 105, 180, 0.6)",e.shadowBlur=15,e.beginPath();for(let n=0;n<6;n++){let f=n*3.14159/3,u=Math.cos(f)*40,o=Math.sin(f)*40;n===0?e.moveTo(u,o):e.lineTo(u,o)}e.closePath(),e.fill(),e.strokeStyle="rgba(255, 255, 255, 0.9)",e.lineWidth=2,e.beginPath(),e.arc(0,0,25,0,3.14159*2),e.stroke(),e.restore(),e.save(),e.font="bold 24px Arial",e.fillStyle="#ffffff",e.shadowColor="#ff00ff",e.shadowBlur=10,e.shadowOffsetX=3,e.shadowOffsetY=3,e.fillText("Awesome Canvas!",350,250),e.strokeStyle="#00ffff",e.lineWidth=1,e.strokeText("Awesome Canvas!",350,250),e.restore(),e.save(),e.translate(500,250);for(let n=0;n<12;n++){let f=n*3.14159/6,u=30,o=Math.cos(f)*u,l=Math.sin(f)*u,s=e.createRadialGradient(o,l,0,o,l,8);s.addColorStop(0,"#ffff00"),s.addColorStop(1,"rgba(255, 255, 0, 0)"),e.fillStyle=s,e.beginPath(),e.arc(o,l,8,0,3.14159*2),e.fill()}e.restore()}async function W(e,r,t){r.fillStyle="#000000",r.font="14px Arial";let a=200,i=20,n=C();t.forEach((f,u)=>{let o=e.width-100,l=n[u%n.length],s;if(l[0]==="linear"){let[w,c,S,B,$,E]=l;s=r.createLinearGradient(50+c*o,a+S*i,50+B*o,a+$*i),E.forEach(([R,k])=>s.addColorStop(R,k))}else{let[w,c,S,B,$,E,R,k]=l;s=r.createRadialGradient(50+c*o,a+S*i,B*50,50+$*o,a+E*i,R*50),k.forEach(([V,K])=>s.addColorStop(V,K))}r.fillStyle=s;let d="",A=f.split(" ");for(let w of A){let c=d+w+" ";r.measureText(c).width>o&&d!==""?(r.fillText(d,50,a),a+=i,d=w+" "):d=c}r.fillText(d,50,a),a+=i+5})}async function G(e,r){let t=await p();t.length<C().length&&t.push("Warning:: Data length less than effect length!"),await P(r,e),await W(e,r,t)}async function I(){let e=document.createElement("canvas");e.width=1920,e.height=1080;let r=e.getContext("2d");return await G(e,r),e}async function _(){let e=new OffscreenCanvas(1920,1080),r=e.getContext("2d");return await G(e,r),await e.convertToBlob()}function Y(e){addEventListener("message",async r=>postMessage({$:e,_:await h(await _())}))}async function N(){if(!globalThis.OffscreenCanvas)throw new Error("OffscreenCanvas is not supported");let e=null,r=null;try{let t=U(2048).toString(),i=`${`${p}${b}${h}${g}${v}${L}${F}${D}${T}${G}${P}${W}${C}${y}${_};globalThis.screen=({width:${screen.width},height:${screen.height},availWidth:${screen.availWidth},availHeight:${screen.availHeight}});`};((${Y}))('${t}');`,n=new Blob([i],{type:"text/javascript"});e=URL.createObjectURL(n);let f=await new Promise((u,o)=>{setTimeout(o,5e3);function l(s){s.data&&s.data.$===t&&(u(s.data._),r&&r.terminate())}r=new Worker(e),r.onerror=o,r.onmessage=l,r.postMessage({})});if(URL.revokeObjectURL(e),f)return f}catch{e&&URL.revokeObjectURL(e),r&&r.terminate()}throw new Error("Failed to use Worker")}var m={value:!1};CanvasRenderingContext2D.prototype.putImageData=new Proxy(CanvasRenderingContext2D.prototype.putImageData,{apply(e,r,t){if(!m.value)return Reflect.apply(e,r,t)}});Math.random=new Proxy(Math.random,{apply(e,r,t){return m.value?.99:Reflect.apply(e,r,t)}});async function H(e){let r=new OffscreenCanvas(e.width,e.height);r.getContext("2d").drawImage(e,0,0),m.value=!0;let a=await r.convertToBlob();return m.value=!1,await h(a)}async function O(){let e=await I();try{return await H(e)}catch{m.value=!0;let t=e.toDataURL("image/png")+";fake;user="+(await p()).join(";");return m.value=!1,t}}async function j(e="",r=0){if(r===2)return await I();if(r===1)return await O();let t=null;try{t=await N()}catch{t=await g(await O())}return await g(t+"@"+e)}export{b as asha256,h as bsha256,j as default,H as exportCanvasData,p as getData,y as isExtensionFuckingCanvas,g as sha256}; //# sourceMappingURL=main.min.js.map