Files
pirate-corsaire-server/Utility/extractBehaviourFeatures.js
T
2026-08-24 22:20:36 +02:00

76 lines
2.1 KiB
JavaScript

function extractBehaviourFeatures(actions) {
if (!actions || actions.length < 2) return null;
const actionCounts = {};
const idleThreshold = 5000;
const windowSize = 5;
const intervals = [];
const sequenceBuffer = [];
let totalInterval = 0;
let minInterval = Infinity;
let maxInterval = -Infinity;
let idleTimeCount = 0;
let idleTimeTotal = 0;
let lastTimestamp = actions[0].timestamp;
let prevAction = actions[0].opcode;
let sequenceMap = {};
for (let i = 1; i < actions.length; i++) {
const current = actions[i];
const interval = current.timestamp - lastTimestamp;
lastTimestamp = current.timestamp;
intervals.push(interval);
totalInterval += interval;
minInterval = Math.min(minInterval, interval);
maxInterval = Math.max(maxInterval, interval);
actionCounts[current.opcode] = (actionCounts[current.opcode] || 0) + 1;
if (interval > idleThreshold) {
idleTimeCount++;
idleTimeTotal += interval;
};
sequenceBuffer.push(current.opcode);
if (sequenceBuffer.length === windowSize) {
const key = sequenceBuffer.join(",");
sequenceMap[key] = (sequenceMap[key] || 0) + 1;
sequenceBuffer.shift();
};
prevAction = current.opcode;
};
const meanInterval = totalInterval / intervals.length;
const stdDevInterval = Math.sqrt(intervals.reduce((sum, val) => sum + (val - meanInterval) ** 2, 0) / intervals.length);
const uniqueActionsCount = Object.keys(actionCounts).length;
const idleTimeRatio = idleTimeCount / (actions.length - 1);
const maxSequenceRepeats = Math.max(...Object.values(sequenceMap)) || 0;
const totalActions = actions.length;
let entropy = 0;
for (const count of Object.values(actionCounts)) {
const p = count / totalActions;
entropy -= p * Math.log2(p);
};
return {
timestamp: new Date(),
timestampStart: null,
meanInterval,
stdDevInterval,
minInterval,
maxInterval,
uniqueActionsCount,
actionEntropy: entropy,
maxSequenceRepeats,
idleTimeRatio
};
};
module.exports = extractBehaviourFeatures;