thumb-browser
Version:
A blazing-fast, dependency-free browser fingerprinting library to uniquely identify devices using entropy data. Designed for high performance, privacy-respecting analytics, bot detection, and session tracking in modern web apps.
2 lines (1 loc) • 2.88 kB
JavaScript
(function(r,s){typeof exports=="object"&&typeof module!="undefined"?module.exports=s():typeof define=="function"&&define.amd?define(s):(r=typeof globalThis!="undefined"?globalThis:r||self,r.Thumb=s())})(this,function(){"use strict";var g=(r,s,t)=>new Promise((e,n)=>{var a=o=>{try{c(t.next(o))}catch(i){n(i)}},u=o=>{try{c(t.throw(o))}catch(i){n(i)}},c=o=>o.done?e(o.value):Promise.resolve(o.value).then(a,u);c((t=t.apply(r,s)).next())});class r{constructor(){this.data=[]}get(){return g(this,null,function*(){yield this.collect();const t=this.data.join("||");return yield this.hash(t)})}collect(){return g(this,null,function*(){this.data=[navigator.userAgent,navigator.language,screen.width+"x"+screen.height+"x"+screen.colorDepth,new Date().getTimezoneOffset(),this.getCanvas(),yield this.getAudio(),this.getWebGL(),navigator.maxTouchPoints,navigator.deviceMemory||"unknown",navigator.hardwareConcurrency||"unknown",Intl.DateTimeFormat().resolvedOptions().timeZone,navigator.doNotTrack,`${window.innerWidth}x${window.innerHeight}`,this.getPlugins(),this.getColorGamut(),this.getBattery(),this.getNetwork(),this.getNoise()]})}getCanvas(){try{const t=document.createElement("canvas"),e=t.getContext("2d");return e.textBaseline="top",e.font="14px Arial",e.fillStyle="#f60",e.fillRect(0,0,100,40),e.fillStyle="#069",e.fillText("🧠 Fingerprint!",2,2),t.toDataURL()}catch(t){return"canvas_unsupported"}}getAudio(){return g(this,null,function*(){try{const t=new(window.OfflineAudioContext||window.webkitOfflineAudioContext)(1,44100,44100),e=t.createOscillator(),n=t.createGain();return e.type="triangle",e.frequency.value=1e4,e.connect(n),n.connect(t.destination),e.start(0),t.startRendering(),new Promise(a=>{t.oncomplete=u=>{const c=u.renderedBuffer.getChannelData(0);let o=0;for(let i=0;i<c.length;i++)o+=Math.abs(c[i]);a(o.toString())}})}catch(t){return"audio_unsupported"}})}getWebGL(){try{const e=document.createElement("canvas").getContext("webgl"),n=e.getExtension("WEBGL_debug_renderer_info"),a=e.getParameter(n.UNMASKED_VENDOR_WEBGL),u=e.getParameter(n.UNMASKED_RENDERER_WEBGL);return`${a}~${u}`}catch(t){return"webgl_unsupported"}}getPlugins(){try{return navigator.plugins?[...navigator.plugins].map(t=>t.name).join(","):"no_plugins"}catch(t){return"plugins_unsupported"}}getColorGamut(){return window.matchMedia("(color-gamut: p3)").matches?"p3":"srgb"}getBattery(){return navigator.getBattery?navigator.getBattery().then(t=>t.level):"battery_unsupported"}getNetwork(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t?t.effectiveType:"network_unsupported"}getNoise(){return Math.random().toString(36).substring(2,15)}hash(t){return g(this,null,function*(){const e=new TextEncoder().encode(t),n=yield crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(n)).map(a=>a.toString(16).padStart(2,"0")).join("")})}}return r});