Last active
August 16, 2020 02:25
-
-
Save a-gu/01bb85f4c94db410f181a77ffd174f50 to your computer and use it in GitHub Desktop.
basic system/browser fingerprinting function for use as a simple but robust user id
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// fingerprint : basic system/browser fingerprinting function | |
// for use as a simple but robust user id | |
function fingerprint() { | |
// hash : simple hash-like function, not guaranteed to return same-size data | |
// or change output greatly on input changes | |
let hash = function (input) { | |
let temp = JSON.stringify(input), | |
out = BigInt(0) | |
for (let i = 0; i < temp.length; i++) { | |
out ^= BigInt(temp.charCodeAt(i)) << BigInt(i % 128) | |
} | |
return out.toString(16) | |
} | |
// webGlInfo : basic information about WebGL, falling back to basic canvas | |
// sizing if unable to access debug info | |
let webGlInfo = function () { | |
let canvas = document.createElement('canvas'), | |
webgl = canvas.getContext('webgl'), | |
render_debug = webgl?.getExtension('WEBGL_debug_renderer_info') | |
if (!render_debug) return [canvas.width, canvas.height] | |
return [ | |
webgl.getParameter(render_debug.UNMASKED_VENDOR_WEBGL), | |
webgl.getParameter(render_debug.UNMASKED_RENDERER_WEBGL) | |
].join() | |
} | |
// canvasData : information about canvas rendering used for fingerprinting, | |
// returns 0 if unable to read from canvas | |
let canvasData = function () { | |
let canvas = document.createElement('canvas'), | |
ctx = canvas.getContext('2d') | |
canvas.width = 180 | |
canvas.height = 50 | |
ctx.fillStyle = 'green' | |
ctx.fillRect(12.4, 6.5, 17.0, 18.6) | |
ctx.strokeStyle = '#ff00004c' | |
ctx.strokeText('Sphinx of black quartz, judge my vow.', 10, 10) | |
ctx.fillStyle = '#0000ab65' | |
ctx.fillRect(0, 8, 150, 15) | |
let data = ctx.getImageData(0, 0, canvas.width, canvas.height).data | |
if (Math.max(...data.slice(0, 20)) > 0) return 0 | |
return data.join() | |
} | |
// fingerprinting parameters | |
return hash([ | |
navigator.appCodeName, | |
navigator.appName, | |
navigator.oscpu, | |
navigator.platform, | |
navigator.product, | |
webGlInfo(), | |
hash(canvasData()), | |
Object.keys(navigator.__proto__) | |
]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment