musealpha / src-tauri /resources /scripts /canvas_noise.js
asdf98's picture
Upload 112 files
3d7d9b5 verified
(function() {
'use strict';
// Add imperceptible noise to canvas fingerprinting attempts
const origToDataURL = HTMLCanvasElement.prototype.toDataURL;
const origToBlob = HTMLCanvasElement.prototype.toBlob;
const origGetImageData = CanvasRenderingContext2D.prototype.getImageData;
function addNoise(ctx, canvas) {
try {
const w = Math.min(canvas.width, 2);
const h = Math.min(canvas.height, 2);
const imageData = ctx.getImageData.call(ctx, 0, 0, w, h);
// Modify one sub-pixel by ±1
const idx = Math.floor(Math.random() * imageData.data.length);
imageData.data[idx] = Math.max(0, Math.min(255, imageData.data[idx] + (Math.random() > 0.5 ? 1 : -1)));
ctx.putImageData(imageData, 0, 0);
} catch(e) { /* cross-origin or tainted canvas */ }
}
HTMLCanvasElement.prototype.toDataURL = function() {
const ctx = this.getContext('2d');
if (ctx) addNoise(ctx, this);
return origToDataURL.apply(this, arguments);
};
HTMLCanvasElement.prototype.toBlob = function() {
const ctx = this.getContext('2d');
if (ctx) addNoise(ctx, this);
return origToBlob.apply(this, arguments);
};
CanvasRenderingContext2D.prototype.getImageData = function() {
const result = origGetImageData.apply(this, arguments);
// Add noise to returned data for fingerprint resistance
if (result.data.length > 4) {
const idx = Math.floor(Math.random() * result.data.length);
result.data[idx] = Math.max(0, Math.min(255, result.data[idx] + (Math.random() > 0.5 ? 1 : -1)));
}
return result;
};
})();