diy
This commit is contained in:
parent
aecbbf2129
commit
b2ad274280
1 changed files with 40 additions and 100 deletions
|
|
@ -21,7 +21,7 @@ if ( hasharray.length > 0 ) {
|
||||||
|
|
||||||
// fingerprint user
|
// fingerprint user
|
||||||
|
|
||||||
const cyrb53 = function (str, seed = 0) {
|
function cyrb53(str, seed = 0){
|
||||||
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
|
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
|
||||||
for (let i = 0, ch; i < str.length; i++) {
|
for (let i = 0, ch; i < str.length; i++) {
|
||||||
ch = str.charCodeAt(i);
|
ch = str.charCodeAt(i);
|
||||||
|
|
@ -33,87 +33,36 @@ const cyrb53 = function (str, seed = 0) {
|
||||||
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateTheAudioFingerPrint = function () {
|
function audioFingerprint() {
|
||||||
var context = null;
|
const AudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContex;
|
||||||
var currentTime = null;
|
const context = new AudioContext(1, 5000, 44100);
|
||||||
var oscillator = null;
|
const oscillator = context.createOscillator();
|
||||||
var compressor = null;
|
oscillator.type = "triangle";
|
||||||
var fingerprint = null;
|
oscillator.frequency.value = 1000;
|
||||||
var callback = null;
|
const compressor = context.createDynamicsCompressor()
|
||||||
function run(debug = false) {
|
compressor.threshold.value = -50;
|
||||||
try {
|
compressor.knee.value = 40;
|
||||||
setup();
|
compressor.ratio.value = 12;
|
||||||
oscillator.connect(compressor);
|
compressor.reduction.value = 20;
|
||||||
compressor.connect(context.destination);
|
compressor.attack.value = 0;
|
||||||
oscillator.start(0);
|
compressor.release.value = 0.2;
|
||||||
context.startRendering();
|
oscillator.connect(compressor);
|
||||||
context.oncomplete = onComplete;
|
compressor.connect(context.destination);
|
||||||
}
|
oscillator.start()
|
||||||
catch (e) {
|
context.oncomplete = event => {
|
||||||
if (debug) {
|
const samples = event.renderedBuffer.getChannelData(0)};
|
||||||
throw e;
|
context.startRendering();
|
||||||
}
|
let hash = 0;
|
||||||
}
|
for (let i = 0; i < samples.length; ++i) {
|
||||||
|
hash += Math.abs(samples[i]);
|
||||||
}
|
}
|
||||||
function setup() {
|
return hash;
|
||||||
setContext();
|
}
|
||||||
currentTime = context.currentTime;
|
|
||||||
setOscillator();
|
|
||||||
setCompressor();
|
|
||||||
}
|
|
||||||
function setContext() {
|
|
||||||
var audioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;
|
|
||||||
context = new audioContext(1, 44100, 44100);
|
|
||||||
}
|
|
||||||
function setOscillator() {
|
|
||||||
oscillator = context.createOscillator();
|
|
||||||
oscillator.type = "triangle";
|
|
||||||
oscillator.frequency.setValueAtTime(10000, currentTime);
|
|
||||||
}
|
|
||||||
function setCompressor() {
|
|
||||||
compressor = context.createDynamicsCompressor();
|
|
||||||
setCompressorValueIfDefined('threshold', -50);
|
|
||||||
setCompressorValueIfDefined('knee', 40);
|
|
||||||
setCompressorValueIfDefined('ratio', 12);
|
|
||||||
setCompressorValueIfDefined('reduction', -20);
|
|
||||||
setCompressorValueIfDefined('attack', 0);
|
|
||||||
setCompressorValueIfDefined('release', .25);
|
|
||||||
}
|
|
||||||
function setCompressorValueIfDefined(item, value) {
|
|
||||||
if (compressor[item] !== undefined && typeof compressor[item].setValueAtTime === 'function') {
|
|
||||||
compressor[item].setValueAtTime(value, context.currentTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function onComplete(event) {
|
|
||||||
generateFingerprints(event);
|
|
||||||
compressor.disconnect();
|
|
||||||
}
|
|
||||||
function generateFingerprints(event) {
|
|
||||||
var output = null;
|
|
||||||
for (var i = 4500; 5e3 > i; i++) {
|
|
||||||
var channelData = event.renderedBuffer.getChannelData(0)[i];
|
|
||||||
output += Math.abs(channelData);
|
|
||||||
}
|
|
||||||
fingerprint = output.toString();
|
|
||||||
if (typeof callback === 'function') {
|
|
||||||
return callback(fingerprint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
run: run
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const getCanvasFingerprint = () => {
|
function canvasFingerprint() {
|
||||||
// If canvas is not supported simply return a static string
|
|
||||||
if (!(0, exports.isCanvasSupported)())
|
|
||||||
return "broprint.js";
|
|
||||||
// draw a canvas of given text and return its data uri
|
|
||||||
// different browser generates different dataUri based on their hardware configs
|
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
var ctx = canvas.getContext('2d');
|
var ctx = canvas.getContext('2d');
|
||||||
// https://www.browserleaks.com/canvas#how-does-it-work
|
var txt = 'Numinous Field Communication';
|
||||||
var txt = 'BroPrint.65@345876';
|
|
||||||
ctx.textBaseline = "top";
|
ctx.textBaseline = "top";
|
||||||
ctx.font = "14px 'Arial'";
|
ctx.font = "14px 'Arial'";
|
||||||
ctx.textBaseline = "alphabetic";
|
ctx.textBaseline = "alphabetic";
|
||||||
|
|
@ -123,29 +72,20 @@ const getCanvasFingerprint = () => {
|
||||||
ctx.fillText(txt, 2, 15);
|
ctx.fillText(txt, 2, 15);
|
||||||
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
|
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
|
||||||
ctx.fillText(txt, 4, 17);
|
ctx.fillText(txt, 4, 17);
|
||||||
return canvas.toDataURL();
|
src = canvas.toDataURL();
|
||||||
|
for (i = 0; i < src.length; i++) {
|
||||||
|
char = src.charCodeAt(i);
|
||||||
|
hash = ((hash<<5)-hash)+char;
|
||||||
|
hash = hash & hash;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getCurrentBrowserFingerPrint() {
|
function getFingerprint() {
|
||||||
const getTheAudioPrints = new Promise((resolve, reject) => {
|
const audioFp = audioFingerprint();
|
||||||
generateTheAudioFingerPrint.run(function (fingerprint) {
|
const canvasFp = canvasFingerprint();
|
||||||
resolve(fingerprint);
|
const hash = cyrb53(audioFp + canvasFp);
|
||||||
});
|
return hash;
|
||||||
});
|
|
||||||
const DevicePrints = new Promise((resolve, reject) => {
|
|
||||||
getTheAudioPrints.then((audioChannelResult) => {
|
|
||||||
let fingerprint = window.btoa(audioChannelResult) + (0, getCanvasFingerprint)();
|
|
||||||
resolve((0, cyrb53)(fingerprint, 0));
|
|
||||||
}).catch(() => {
|
|
||||||
try {
|
|
||||||
resolve((0, cyrb53)((0, getCanvasFingerprint)()).toString());
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
reject("Failed to generate the finger print of this browser");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return DevicePrints;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(getCurrentBrowserFingerPrint());
|
console.log(getFingerprint());
|
||||||
Loading…
Add table
Add a link
Reference in a new issue