by Proze

Full browser fingerprinting evasion suite.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey to install this script.

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name        by Proze
// @namespace   Violentmonkey Scripts
// @match       *://*/*
// @grant       none
// @run-at      document-start
// @version     10.0
// @author      .*
// @description Full browser fingerprinting evasion suite.
// @license     MIT
// ==/UserScript==

(function() {
    'use strict';

    const D = {
        os: [
            { n: "Windows NT 10.0; Win64; x64", p: "Win32", v: "Google Inc.", m: "desktop" },
            { n: "Windows NT 10.0; WOW64", p: "Win32", v: "Google Inc.", m: "desktop" },
            { n: "Macintosh; Intel Mac OS X 10_15_7", p: "MacIntel", v: "Apple Computer, Inc.", m: "desktop" },
            { n: "Macintosh; Intel Mac OS X 12_3_1", p: "MacIntel", v: "Apple Computer, Inc.", m: "desktop" },
            { n: "X11; Linux x86_64", p: "Linux x86_64", v: "Google Inc.", m: "desktop" },
            { n: "Linux; Android 13; SM-S908B", p: "Linux armv8l", v: "Google Inc.", m: "mobile" },
            { n: "Linux; Android 12; Pixel 6 Pro", p: "Linux armv8l", v: "Google Inc.", m: "mobile" },
            { n: "iPhone; CPU iPhone OS 16_0 like Mac OS X", p: "iPhone", v: "Apple Computer, Inc.", m: "mobile" },
            { n: "iPad; CPU OS 15_4 like Mac OS X", p: "iPad", v: "Apple Computer, Inc.", m: "mobile" }
        ],
        browser: [
            "Chrome/108.0.0.0", "Chrome/109.0.0.0", "Chrome/110.0.0.0",
            "Safari/605.1.15", "Firefox/109.0", "Firefox/108.0"
        ],
        gpu: [
            "ANGLE (NVIDIA, NVIDIA GeForce RTX 3090 Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "ANGLE (NVIDIA, NVIDIA GeForce RTX 3080 Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "ANGLE (NVIDIA, NVIDIA GeForce GTX 1080 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "ANGLE (AMD, AMD Radeon RX 6900 XT Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "Apple GPU", "Apple A15 GPU", "Apple A16 GPU", "Adreno (TM) 730", "Mali-G710 MC10"
        ],
        tz: [
            { z: "America/New_York", o: 300, l: "en-US" }, { z: "America/Los_Angeles", o: 480, l: "en-US" },
            { z: "Europe/London", o: 0, l: "en-GB" }, { z: "Europe/Berlin", o: -60, l: "de-DE" },
            { z: "Asia/Tokyo", o: -540, l: "ja-JP" }, { z: "Asia/Singapore", o: -480, l: "en-SG" }
        ]
    };

    function r(a) { return a[Math.floor(Math.random() * a.length)]; }
    function ri(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
    function rf() { return Math.random() * 0.0000001; }

    const sOS = r(D.os);
    const sBr = r(D.browser);
    const sUA = `Mozilla/5.0 (${sOS.n}) AppleWebKit/537.36 (KHTML, like Gecko) ${sBr} Safari/537.36`;
    const sGpu = r(D.gpu);
    const sTz = r(D.tz);
    const sW = sOS.m === "mobile" ? ri(360, 430) : ri(1366, 2560);
    const sH = sOS.m === "mobile" ? ri(640, 932) : ri(768, 1440);
    const sDPR = sOS.m === "mobile" ? ri(2, 3) : 1;
    const sMem = [4, 8, 12, 16, 32][ri(0, 4)];
    const sCon = [4, 6, 8, 12, 16, 24][ri(0, 5)];
    const sBat = Math.random();
    const sChg = Math.random() > 0.5;

    function inject(scope) {
        function def(o, p, v) {
            try { Object.defineProperty(scope.Object.getPrototypeOf(o), p, { get: () => v, configurable: true, enumerable: true }); } catch(e) {}
            try { Object.defineProperty(o, p, { get: () => v, configurable: true, enumerable: true }); } catch(e) {}
        }

        def(scope.navigator, 'userAgent', sUA);
        def(scope.navigator, 'appVersion', sUA.replace('Mozilla/', ''));
        def(scope.navigator, 'platform', sOS.p);
        def(scope.navigator, 'vendor', sOS.v);
        def(scope.navigator, 'hardwareConcurrency', sCon);
        def(scope.navigator, 'deviceMemory', sMem);
        def(scope.navigator, 'maxTouchPoints', sOS.m === "mobile" ? ri(2, 5) : 0);
        def(scope.navigator, 'webdriver', false);
        def(scope.navigator, 'doNotTrack', "1");
        def(scope.navigator, 'language', sTz.l);
        def(scope.navigator, 'languages', [sTz.l, 'en-US']);
        
        if (scope.navigator.plugins) {
            def(scope.navigator, 'plugins', []);
            def(scope.navigator, 'mimeTypes', []);
        }

        def(scope.screen, 'width', sW);
        def(scope.screen, 'height', sH);
        def(scope.screen, 'availWidth', sW);
        def(scope.screen, 'availHeight', sH - 40);
        def(scope.screen, 'colorDepth', 24);
        def(scope.screen, 'pixelDepth', 24);
        
        def(scope.window, 'devicePixelRatio', sDPR);
        def(scope.window, 'innerWidth', sW);
        def(scope.window, 'innerHeight', sH);
        def(scope.window, 'outerWidth', sW);
        def(scope.window, 'outerHeight', sH);

        try {
            const gP = scope.WebGLRenderingContext.prototype.getParameter;
            scope.WebGLRenderingContext.prototype.getParameter = function(p) {
                if (p === 37445) return "Google Inc. (NVIDIA)";
                if (p === 37446) return sGpu;
                return gP.apply(this, arguments);
            };
        } catch(e) {}

        try {
            const tDU = scope.HTMLCanvasElement.prototype.toDataURL;
            scope.HTMLCanvasElement.prototype.toDataURL = function() {
                const c = this.getContext('2d');
                if (c) {
                    const w = this.width;
                    const h = this.height;
                    const d = c.getImageData(0, 0, w, h);
                    for (let i = 0; i < d.data.length; i += 4) {
                        if (i % ri(500, 2000) === 0) d.data[i] = d.data[i] + (Math.random() > 0.5 ? 1 : -1);
                    }
                    c.putImageData(d, 0, 0);
                }
                return tDU.apply(this, arguments);
            };
        } catch(e) {}

        try {
            const oAC = scope.AudioContext || scope.webkitAudioContext;
            if (oAC) {
                const oAn = oAC.prototype.createAnalyser;
                oAC.prototype.createAnalyser = function() {
                    const a = oAn.apply(this, arguments);
                    const oG = a.getFloatFrequencyData;
                    a.getFloatFrequencyData = function(arr) {
                        const r = oG.apply(this, arguments);
                        for (let i = 0; i < arr.length; i += 10) arr[i] += (Math.random() * 0.1) - 0.05;
                        return r;
                    };
                    return a;
                };
            }
        } catch(e) {}

        try {
            const oRTC = scope.RTCPeerConnection || scope.webkitRTCPeerConnection || scope.mozRTCPeerConnection;
            if (oRTC) {
                scope.RTCPeerConnection = function(c) {
                    if (c && c.iceServers) c.iceServers = [];
                    const p = new oRTC(c);
                    const oO = p.createOffer;
                    p.createOffer = function(o) { return oO.call(this, o).then(f => f); };
                    return p;
                };
                scope.RTCPeerConnection.prototype = oRTC.prototype;
            }
        } catch(e) {}

        try {
            const mTxt = scope.CanvasRenderingContext2D.prototype.measureText;
            scope.CanvasRenderingContext2D.prototype.measureText = function(t) {
                const m = mTxt.apply(this, arguments);
                const n = (Math.random() * 0.01) - 0.005;
                try { Object.defineProperty(m, 'width', { get: () => m.width + n }); } catch(e) { m.width = m.width + n; }
                return m;
            };
        } catch(e) {}

        try {
            const oBCR = scope.Element.prototype.getBoundingClientRect;
            scope.Element.prototype.getBoundingClientRect = function() {
                const r = oBCR.apply(this, arguments);
                const n = rf();
                return { x: r.x + n, y: r.y + n, width: r.width + n, height: r.height + n, top: r.top + n, right: r.right + n, bottom: r.bottom + n, left: r.left + n, toJSON: () => this };
            };
        } catch(e) {}

        try {
            const oNow = scope.performance.now;
            scope.performance.now = function() { return oNow.apply(this) + (Math.random() * 0.02); };
        } catch(e) {}

        if (scope.navigator.getBattery) {
            scope.navigator.getBattery = () => Promise.resolve({ charging: sChg, chargingTime: sChg ? ri(100, 5000) : Infinity, dischargingTime: sChg ? Infinity : ri(100, 50000), level: sBat, addEventListener: () => {}, removeEventListener: () => {} });
        }

        if (scope.navigator.permissions) {
            scope.navigator.permissions.query = p => Promise.resolve({ state: 'prompt', onchange: null });
        }

        const oIntl = scope.Intl.DateTimeFormat;
        scope.Intl.DateTimeFormat = function(l, o) {
            if (!o) o = {};
            if (!o.timeZone) o.timeZone = sTz.z;
            return new oIntl(l, o);
        };
        scope.Intl.DateTimeFormat.prototype = oIntl.prototype;
    }

    inject(window);

    const observer = new MutationObserver(mutations => {
        mutations.forEach(m => {
            m.addedNodes.forEach(n => {
                if (n.tagName === 'IFRAME') {
                    try {
                        if (n.contentWindow) inject(n.contentWindow);
                        n.addEventListener('load', () => inject(n.contentWindow));
                    } catch(e) {}
                }
            });
        });
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });

    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;

})();