From 58512876cd8b483d88f3eb01828645cacb77b1a3 Mon Sep 17 00:00:00 2001 From: Macide Celik Date: Tue, 29 Oct 2019 09:01:15 +0300 Subject: [PATCH] Delete Entropy.mjs --- src/core/operations/Entropy.mjs | 430 -------------------------------- 1 file changed, 430 deletions(-) delete mode 100644 src/core/operations/Entropy.mjs diff --git a/src/core/operations/Entropy.mjs b/src/core/operations/Entropy.mjs deleted file mode 100644 index 3e93cc57..00000000 --- a/src/core/operations/Entropy.mjs +++ /dev/null @@ -1,430 +0,0 @@ -/** - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - */ - -import * as d3temp from "d3"; -import * as nodomtemp from "nodom"; - -import Operation from "../Operation.mjs"; - -const d3 = d3temp.default ? d3temp.default : d3temp; -const nodom = nodomtemp.default ? nodomtemp.default: nodomtemp; - -/** - * Entropy operation - */ -class Entropy extends Operation { - - /** - * Entropy constructor - */ - constructor() { - super(); - - this.name = "Entropy"; - this.module = "Charts"; - this.description = "Shannon Entropy, in the context of information theory, is a measure of the rate at which information is produced by a source of data. It can be used, in a broad sense, to detect whether data is likely to be structured or unstructured. 8 is the maximum, representing highly unstructured, 'random' data. English language text usually falls somewhere between 3.5 and 5. Properly encrypted or compressed data should have an entropy of over 7.5."; - this.infoURL = "https://wikipedia.org/wiki/Entropy_(information_theory)"; - this.inputType = "ArrayBuffer"; - this.outputType = "json"; - this.presentType = "html"; - this.args = [ - { - "name": "Visualisation", - "type": "option", - "value": ["Shannon scale", "Histogram (Bar)", "Histogram (Line)", "Curve", "Image"] - } - ]; - } - - /** - * Calculates the frequency of bytes in the input. - * - * @param {Uint8Array} input - * @returns {number} - */ - calculateShannonEntropy(input) { - const prob = [], - occurrences = new Array(256).fill(0); - - // Count occurrences of each byte in the input - let i; - for (i = 0; i < input.length; i++) { - occurrences[input[i]]++; - } - - // Store probability list - for (i = 0; i < occurrences.length; i++) { - if (occurrences[i] > 0) { - prob.push(occurrences[i] / input.length); - } - } - - // Calculate Shannon entropy - let entropy = 0, - p; - - for (i = 0; i < prob.length; i++) { - p = prob[i]; - entropy += p * Math.log(p) / Math.log(2); - } - - return -entropy; - } - - /** - * Calculates the scanning entropy of the input - * - * @param {Uint8Array} inputBytes - * @returns {Object} - */ - calculateScanningEntropy(inputBytes) { - const entropyData = []; - const binWidth = inputBytes.length < 256 ? 8 : 256; - - for (let bytePos = 0; bytePos < inputBytes.length; bytePos += binWidth) { - const block = inputBytes.slice(bytePos, bytePos+binWidth); - entropyData.push(this.calculateShannonEntropy(block)); - } - - return { entropyData, binWidth }; - } - - /** - * Calculates the frequency of bytes in the input. - * - * @param {object} svg - * @param {function} xScale - * @param {function} yScale - * @param {integer} svgHeight - * @param {integer} svgWidth - * @param {object} margins - * @param {string} xTitle - * @param {string} yTitle - */ - createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, title, xTitle, yTitle) { - // Axes - const yAxis = d3.axisLeft() - .scale(yScale); - - const xAxis = d3.axisBottom() - .scale(xScale); - - svg.append("g") - .attr("transform", `translate(0, ${svgHeight - margins.bottom})`) - .call(xAxis); - - svg.append("g") - .attr("transform", `translate(${margins.left},0)`) - .call(yAxis); - - // Axes labels - svg.append("text") - .attr("transform", "rotate(-90)") - .attr("y", 0 - margins.left) - .attr("x", 0 - (svgHeight / 2)) - .attr("dy", "1em") - .style("text-anchor", "middle") - .text(yTitle); - - svg.append("text") - .attr("transform", `translate(${svgWidth / 2}, ${svgHeight - margins.bottom + 40})`) - .style("text-anchor", "middle") - .text(xTitle); - - // Add title - svg.append("text") - .attr("transform", `translate(${svgWidth / 2}, ${margins.top - 10})`) - .style("text-anchor", "middle") - .text(title); - } - - /** - * Calculates the frequency of bytes in the input. - * - * @param {Uint8Array} inputBytes - * @returns {number[]} - */ - calculateByteFrequency(inputBytes) { - const freq = new Array(256).fill(0); - if (inputBytes.length === 0) return freq; - - // Count occurrences of each byte in the input - let i; - for (i = 0; i < inputBytes.length; i++) { - freq[inputBytes[i]]++; - } - - for (i = 0; i < freq.length; i++) { - freq[i] = freq[i] / inputBytes.length; - } - - return freq; - } - - /** - * Calculates the frequency of bytes in the input. - * - * @param {number[]} byteFrequency - * @returns {HTML} - */ - createByteFrequencyLineHistogram(byteFrequency) { - const margins = { top: 30, right: 20, bottom: 50, left: 30 }; - - const svgWidth = 500, - svgHeight = 500; - - const document = new nodom.Document(); - let svg = document.createElement("svg"); - - svg = d3.select(svg) - .attr("width", "100%") - .attr("height", "100%") - .attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`); - - const yScale = d3.scaleLinear() - .domain([0, d3.max(byteFrequency, d => d)]) - .range([svgHeight - margins.bottom, margins.top]); - - const xScale = d3.scaleLinear() - .domain([0, byteFrequency.length - 1]) - .range([margins.left, svgWidth - margins.right]); - - const line = d3.line() - .x((_, i) => xScale(i)) - .y(d => yScale(d)) - .curve(d3.curveMonotoneX); - - svg.append("path") - .datum(byteFrequency) - .attr("fill", "none") - .attr("stroke", "steelblue") - .attr("d", line); - - this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "", "Byte", "Byte Frequency"); - - return svg._groups[0][0].outerHTML; - } - - /** - * Creates a byte frequency histogram - * - * @param {number[]} byteFrequency - * @returns {HTML} - */ - createByteFrequencyBarHistogram(byteFrequency) { - const margins = { top: 30, right: 20, bottom: 50, left: 30 }; - - const svgWidth = 500, - svgHeight = 500, - binWidth = 1; - - const document = new nodom.Document(); - let svg = document.createElement("svg"); - svg = d3.select(svg) - .attr("width", "100%") - .attr("height", "100%") - .attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`); - - const yExtent = d3.extent(byteFrequency, d => d); - const yScale = d3.scaleLinear() - .domain(yExtent) - .range([svgHeight - margins.bottom, margins.top]); - - const xScale = d3.scaleLinear() - .domain([0, byteFrequency.length - 1]) - .range([margins.left - binWidth, svgWidth - margins.right]); - - svg.selectAll("rect") - .data(byteFrequency) - .enter().append("rect") - .attr("x", (_, i) => xScale(i) + binWidth) - .attr("y", dataPoint => yScale(dataPoint)) - .attr("width", binWidth) - .attr("height", dataPoint => yScale(yExtent[0]) - yScale(dataPoint)) - .attr("fill", "blue"); - - this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "", "Byte", "Byte Frequency"); - - return svg._groups[0][0].outerHTML; - } - - /** - * Creates a byte frequency histogram - * - * @param {number[]} entropyData - * @returns {HTML} - */ - createEntropyCurve(entropyData) { - const margins = { top: 30, right: 20, bottom: 50, left: 30 }; - - const svgWidth = 500, - svgHeight = 500; - - const document = new nodom.Document(); - let svg = document.createElement("svg"); - svg = d3.select(svg) - .attr("width", "100%") - .attr("height", "100%") - .attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`); - - const yScale = d3.scaleLinear() - .domain([0, d3.max(entropyData, d => d)]) - .range([svgHeight - margins.bottom, margins.top]); - - const xScale = d3.scaleLinear() - .domain([0, entropyData.length]) - .range([margins.left, svgWidth - margins.right]); - - const line = d3.line() - .x((_, i) => xScale(i)) - .y(d => yScale(d)) - .curve(d3.curveMonotoneX); - - if (entropyData.length > 0) { - svg.append("path") - .datum(entropyData) - .attr("d", line); - - svg.selectAll("path").attr("fill", "none").attr("stroke", "steelblue"); - } - - this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "Scanning Entropy", "Block", "Entropy"); - - return svg._groups[0][0].outerHTML; - } - - /** - * Creates an image representation of the entropy - * - * @param {number[]} entropyData - * @returns {HTML} - */ - createEntropyImage(entropyData) { - const svgHeight = 100, - svgWidth = 100, - cellSize = 1, - nodes = []; - - for (let i = 0; i < entropyData.length; i++) { - nodes.push({ - x: i % svgWidth, - y: Math.floor(i / svgWidth), - entropy: entropyData[i] - }); - } - - const document = new nodom.Document(); - let svg = document.createElement("svg"); - svg = d3.select(svg) - .attr("width", "100%") - .attr("height", "100%") - .attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`); - - const greyScale = d3.scaleLinear() - .domain([0, d3.max(entropyData, d => d)]) - .range(["#000000", "#FFFFFF"]) - .interpolate(d3.interpolateRgb); - - svg - .selectAll("rect") - .data(nodes) - .enter().append("rect") - .attr("x", d => d.x * cellSize) - .attr("y", d => d.y * cellSize) - .attr("width", cellSize) - .attr("height", cellSize) - .style("fill", d => greyScale(d.entropy)); - - return svg._groups[0][0].outerHTML; - } - - /** - * Displays the entropy as a scale bar for web apps. - * - * @param {number} entropy - * @returns {HTML} - */ - createShannonEntropyVisualization(entropy) { - return `Shannon entropy: ${entropy} -

- - 0 represents no randomness (i.e. all the bytes in the data have the same value) whereas 8, the maximum, represents a completely random string. - - Standard English text usually falls somewhere between 3.5 and 5. - - Properly encrypted or compressed data of a reasonable length should have an entropy of over 7.5. - - The following results show the entropy of chunks of the input data. Chunks with particularly high entropy could suggest encrypted or compressed sections. - -
`; - } - - /** - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {json} - */ - run(input, args) { - const visualizationType = args[0]; - input = new Uint8Array(input); - - switch (visualizationType) { - case "Histogram (Bar)": - case "Histogram (Line)": - return this.calculateByteFrequency(input); - case "Curve": - case "Image": - return this.calculateScanningEntropy(input).entropyData; - case "Shannon scale": - default: - return this.calculateShannonEntropy(input); - } - } - - /** - * Displays the entropy in a visualisation for web apps. - * - * @param {json} entropyData - * @param {Object[]} args - * @returns {html} - */ - present(entropyData, args) { - const visualizationType = args[0]; - - switch (visualizationType) { - case "Histogram (Bar)": - return this.createByteFrequencyBarHistogram(entropyData); - case "Histogram (Line)": - return this.createByteFrequencyLineHistogram(entropyData); - case "Curve": - return this.createEntropyCurve(entropyData); - case "Image": - return this.createEntropyImage(entropyData); - case "Shannon scale": - default: - return this.createShannonEntropyVisualization(entropyData); - } - } -} - -export default Entropy;