PageSourceSearch

https://wallpapers.com/static/js/wpc_fp.js

js wallpapers.com collected 2026-10-09 21:29:11 UTC 4,054 bytes, 93 lines download raw bytes

1// wpc_fp.js — lightweight, privacy-scoped device fingerprint for ANONYMOUS
2// tool-credit accounting. All signals stay on our own origin; nothing is sent
3// to any third party (no FingerprintJS / external service), so this is safe for
4// our EU traffic as a fraud-prevention legitimate interest.
5//
6// Why it exists: tool credits are the only gate, and an anon identity used to be
7// hash(IP + session-cookie) — clearing cookies / incognito minted a brand-new
8// identity and refilled the free credit. This fingerprint is DETERMINISTIC: if
9// the user wipes cookies AND localStorage it recomputes the SAME id from device
10// signals, so storage clearing can't refill credits. The server keys the anon
11// grant on sha256(IP + wpc_fp); only a genuinely different device/browser
12// changes it. Stable URL → a JS edit is a single-URL CDN purge.
13(function () {
14  var COOKIE = 'wpc_fp', LS = 'wpc_fp', MAXAGE = 60 * 60 * 24 * 365;
15
16  // cyrb53 — fast non-crypto hash; we only need a stable, well-distributed id
17  // from the concatenated signal string (collision risk between distinct device
18  // strings is negligible for this purpose).
19  function cyrb53(str, seed) {
20    seed = seed || 0;
21    var h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
22    for (var i = 0, ch; i < str.length; i++) {
23      ch = str.charCodeAt(i);
24      h1 = Math.imul(h1 ^ ch, 2654435761);
25      h2 = Math.imul(h2 ^ ch, 1597334677);
26    }
27    h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
28    h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
29    h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
30    h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
31    return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
32  }
33
34  function signals() {
35    var s = [];
36    try { s.push(navigator.userAgent || ''); } catch (e) {}
37    try { s.push(navigator.language || ''); } catch (e) {}
38    try { s.push((navigator.languages || []).join(',')); } catch (e) {}
39    try { s.push(navigator.platform || ''); } catch (e) {}
40    try { s.push((navigator.hardwareConcurrency || '') + ''); } catch (e) {}
41    try { s.push((navigator.deviceMemory || '') + ''); } catch (e) {}
42    try { s.push(screen.width + 'x' + screen.height + 'x' + screen.colorDepth); } catch (e) {}
43    try { s.push('' + new Date().getTimezoneOffset()); } catch (e) {}
44    try { s.push(Intl.DateTimeFormat().resolvedOptions().timeZone || ''); } catch (e) {}
45    // canvas render — GPU/driver/font rasterisation differences
46    try {
47      var c = document.createElement('canvas'); c.width = 200; c.height = 40;
48      var x = c.getContext('2d');
49      x.textBaseline = 'top'; x.font = "14px 'Arial'";
50      x.fillStyle = '#f60'; x.fillRect(120, 1, 60, 20);
51      x.fillStyle = '#069'; x.fillText('wpc-fp-\u{1F600}', 2, 15);
52      s.push(c.toDataURL());
53    } catch (e) {}
54    // WebGL vendor/renderer — distinguishes GPUs
55    try {
56      var gl = document.createElement('canvas').getContext('webgl') ||
57               document.createElement('canvas').getContext('experimental-webgl');
58      if (gl) {
59        var d = gl.getExtension('WEBGL_debug_renderer_info');
60        if (d) {
61          s.push(gl.getParameter(d.UNMASKED_VENDOR_WEBGL));
62          s.push(gl.getParameter(d.UNMASKED_RENDERER_WEBGL));
63        }
64      }
65    } catch (e) {}
66    return s.join('||');
67  }
68
69  function compute() {
70    var cached;
71    try { cached = localStorage.getItem(LS); } catch (e) {}
72    if (cached) return cached;
73    var fp = cyrb53(signals());
74    try { localStorage.setItem(LS, fp); } catch (e) {}
75    return fp;
76  }
77
78  function setCookie(v) {
79    try {
80      var sec = location.protocol === 'https:' ? '; Secure' : '';
81      document.cookie = COOKIE + '=' + v + '; Max-Age=' + MAXAGE +
82                        '; Path=/; SameSite=Lax' + sec;
83    } catch (e) {}
84  }
85
86  try {
87    var fp = compute();
88    window.wpcFP = fp;
89    // Always (re)assert the cookie so a cookie-only clear is repaired from the
90    // localStorage cache / recompute on the very next page view.
91    setCookie(fp);
92  } catch (e) { /* never block the page */ }
93})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.