Skip to content

Instantly share code, notes, and snippets.

@a-gu
Last active August 16, 2020 02:25
Show Gist options
  • Save a-gu/01bb85f4c94db410f181a77ffd174f50 to your computer and use it in GitHub Desktop.
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
// 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