6 Commits

Author SHA1 Message Date
Valentin Silyutin
b203729e0e v1.1.0 2025-09-23 20:53:18 +04:00
Valentin Silyutin
dc5c6f0c25 Fix getVoices() 2025-09-23 20:52:17 +04:00
Valentin Silyutin
5405585cea Add fingerprint example 2025-09-23 17:06:04 +04:00
Valentin Silyutin
0755a26783 Remove sha256() 2025-09-23 17:01:01 +04:00
Valentin Silyutin
8f548f66d5 Fix README.md 2025-09-23 16:48:21 +04:00
Valentin Silyutin
c9751a19d7 Fix README.md 2025-09-23 16:34:54 +04:00
4 changed files with 1541 additions and 17 deletions

View File

@@ -1 +1,6 @@
## v1.1.0
- Удалена функция `sha256()`
- Исправлена работа функции `getVoices()`
## v1.0.0 ## v1.0.0

1517
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,5 @@
/* eslint-disable unicorn/no-null */ /* eslint-disable unicorn/no-null */
const sha256 = async (str) => {
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));
return [...new Uint8Array(buf)].map((b) => b.toString(16).padStart(2, '0')).join('');
};
const getCanvasFingerprint = async () => { const getCanvasFingerprint = async () => {
try { try {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
@@ -18,7 +13,7 @@ const getCanvasFingerprint = async () => {
ctx.fillRect(0, 0, 50, 30); ctx.fillRect(0, 0, 50, 30);
ctx.fillStyle = '#069'; ctx.fillStyle = '#069';
ctx.fillText('fingerprint123', 2, 2); ctx.fillText('fingerprint123', 2, 2);
return await sha256(canvas.toDataURL()); return canvas.toDataURL();
} catch { } catch {
return null; return null;
} }
@@ -46,7 +41,7 @@ const getWebGLFingerprint = async () => {
stencilBits: gl.getParameter(gl.STENCIL_BITS), stencilBits: gl.getParameter(gl.STENCIL_BITS),
extensions: gl.getSupportedExtensions(), extensions: gl.getSupportedExtensions(),
}; };
return { hash: await sha256(JSON.stringify(props)), props }; return props;
} catch { } catch {
return null; return null;
} }
@@ -68,7 +63,7 @@ const getAudioFingerprint = async () => {
let sum = 0; let sum = 0;
const data = buf.getChannelData(0); const data = buf.getChannelData(0);
for (let i = 0; i < data.length; i += 100) sum += Math.abs(data[i]); for (let i = 0; i < data.length; i += 100) sum += Math.abs(data[i]);
return await sha256(String(sum)); return sum;
} catch { } catch {
return null; return null;
} }
@@ -91,7 +86,7 @@ const getMathFingerprint = async () => {
toExp: (123_456_789).toExponential(20), toExp: (123_456_789).toExponential(20),
oneDivNegZero: 1 / -0, oneDivNegZero: 1 / -0,
}; };
return await sha256(JSON.stringify(values)); return values;
} catch { } catch {
return null; return null;
} }
@@ -136,15 +131,28 @@ const getStorage = async () => {
} }
}; };
const getVoices = () => { const getVoices = async () => {
try { try {
if (!window.speechSynthesis) return null; if (!window.speechSynthesis) return null;
return window.speechSynthesis.getVoices().map((v) => ({
const mapVoice = (v) => ({
name: v.name, name: v.name,
lang: v.lang, lang: v.lang,
local: v.localService, local: v.localService,
default: v.default, default: v.default,
})); });
const voices = window.speechSynthesis.getVoices();
if (voices.length > 0) {
return voices.map((v) => mapVoice(v));
}
return await new Promise((resolve) => {
window.speechSynthesis.onvoiceschanged = () => {
const list = window.speechSynthesis.getVoices();
resolve(list.map((v) => mapVoice(v)));
};
});
} catch { } catch {
return null; return null;
} }
@@ -272,7 +280,7 @@ export const get = async () => {
mimes: [...(navigator.mimeTypes ?? [])].map(({ type, suffixes }) => ({ type, suffixes })), mimes: [...(navigator.mimeTypes ?? [])].map(({ type, suffixes }) => ({ type, suffixes })),
// Voices // Voices
voices: getVoices(), voices: await getVoices(),
// Network // Network
network: getNetwork(), network: getNetwork(),

View File

@@ -1,6 +1,6 @@
{ {
"name": "@advdominion/fingerprint", "name": "@advdominion/fingerprint",
"version": "1.0.0", "version": "1.1.0",
"type": "module", "type": "module",
"packageManager": "yarn@4.9.4", "packageManager": "yarn@4.9.4",
"main": "index.js", "main": "index.js",