Fixed formatting issues
This commit is contained in:
parent
b7fb9635e5
commit
8fc0e012e3
@ -26,8 +26,8 @@ class AdvancedEntropy extends Operation {
|
|||||||
|
|
||||||
this.name = "Advanced Entropy";
|
this.name = "Advanced Entropy";
|
||||||
this.module = "Default";
|
this.module = "Default";
|
||||||
this.description = "Adds advanced views for examining entropy";
|
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 = "";
|
this.infoURL = "https://wikipedia.org/wiki/Entropy_(information_theory)";
|
||||||
this.inputType = "byteArray";
|
this.inputType = "byteArray";
|
||||||
this.outputType = "html";
|
this.outputType = "html";
|
||||||
this.args = [
|
this.args = [
|
||||||
@ -41,16 +41,16 @@ class AdvancedEntropy extends Operation {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the frequency of bytes in the input.
|
* Calculates the frequency of bytes in the input.
|
||||||
*
|
*
|
||||||
* @param {byteArray} input
|
* @param {byteArray} input
|
||||||
* @returns {frequency}
|
* @returns {frequency}
|
||||||
*/
|
*/
|
||||||
calculateShannonEntropy(input) {
|
calculateShannonEntropy(input) {
|
||||||
const prob = [],
|
const prob = [],
|
||||||
uniques = input.unique(),
|
uniques = input.unique(),
|
||||||
str = Utils.byteArrayToChars(input);
|
str = Utils.byteArrayToChars(input);
|
||||||
let i;
|
|
||||||
|
|
||||||
|
let i;
|
||||||
for (i = 0; i < uniques.length; i++) {
|
for (i = 0; i < uniques.length; i++) {
|
||||||
prob.push(str.count(Utils.chr(uniques[i])) / input.length);
|
prob.push(str.count(Utils.chr(uniques[i])) / input.length);
|
||||||
}
|
}
|
||||||
@ -66,21 +66,20 @@ class AdvancedEntropy extends Operation {
|
|||||||
return -entropy;
|
return -entropy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param inputBytes
|
||||||
* @returns {entropyData}
|
* @returns {entropyData}
|
||||||
*/
|
*/
|
||||||
calculateScanningEntropy(inputBytes, binWidth) {
|
calculateScanningEntropy(inputBytes, binWidth) {
|
||||||
const entropyData = [];
|
const entropyData = [];
|
||||||
binWidth = binWidth
|
binWidth = binWidth ?
|
||||||
? Math.floor(inputBytes.length / binWidth)
|
Math.floor(inputBytes.length / binWidth) :
|
||||||
: Math.floor(inputBytes.length / 256);
|
Math.floor(inputBytes.length / 256);
|
||||||
|
|
||||||
for (let bytePos = 0; bytePos < inputBytes.length; bytePos+=binWidth) {
|
for (let bytePos = 0; bytePos < inputBytes.length; bytePos+=binWidth) {
|
||||||
const block = inputBytes.slice(bytePos, bytePos+binWidth)
|
const block = inputBytes.slice(bytePos, bytePos+binWidth);
|
||||||
const blockEntropy = this.calculateShannonEntropy(block);
|
entropyData.push(this.calculateShannonEntropy(block));
|
||||||
entropyData.push(blockEntropy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { entropyData, binWidth };
|
return { entropyData, binWidth };
|
||||||
@ -89,7 +88,7 @@ class AdvancedEntropy extends Operation {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the frequency of bytes in the input.
|
* Calculates the frequency of bytes in the input.
|
||||||
*
|
*
|
||||||
* @param {object} svg
|
* @param {object} svg
|
||||||
* @param {function} xScale
|
* @param {function} xScale
|
||||||
* @param {function} yScale
|
* @param {function} yScale
|
||||||
@ -106,7 +105,7 @@ class AdvancedEntropy extends Operation {
|
|||||||
.scale(yScale);
|
.scale(yScale);
|
||||||
|
|
||||||
const xAxis = d3.axisBottom()
|
const xAxis = d3.axisBottom()
|
||||||
.scale(xScale)
|
.scale(xScale);
|
||||||
|
|
||||||
svg.append("g")
|
svg.append("g")
|
||||||
.attr("transform", `translate(0, ${svgHeight - margins.bottom})`)
|
.attr("transform", `translate(0, ${svgHeight - margins.bottom})`)
|
||||||
@ -123,39 +122,37 @@ class AdvancedEntropy extends Operation {
|
|||||||
.attr("x", 0 - (svgHeight / 2))
|
.attr("x", 0 - (svgHeight / 2))
|
||||||
.attr("dy", "1em")
|
.attr("dy", "1em")
|
||||||
.style("text-anchor", "middle")
|
.style("text-anchor", "middle")
|
||||||
.text(yTitle)
|
.text(yTitle);
|
||||||
|
|
||||||
svg.append("text")
|
svg.append("text")
|
||||||
.attr("transform", `translate(${svgWidth / 2}, ${svgHeight - margins.bottom + 40})`)
|
.attr("transform", `translate(${svgWidth / 2}, ${svgHeight - margins.bottom + 40})`)
|
||||||
.style("text-anchor", "middle")
|
.style("text-anchor", "middle")
|
||||||
.text(xTitle)
|
.text(xTitle);
|
||||||
|
|
||||||
// Add title
|
// Add title
|
||||||
svg.append("text")
|
svg.append("text")
|
||||||
.attr("transform", `translate(${svgWidth / 2}, ${margins.top - 10})`)
|
.attr("transform", `translate(${svgWidth / 2}, ${margins.top - 10})`)
|
||||||
.style("text-anchor", "middle")
|
.style("text-anchor", "middle")
|
||||||
.text(title)
|
.text(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the frequency of bytes in the input.
|
* Calculates the frequency of bytes in the input.
|
||||||
*
|
*
|
||||||
* @param {byteArray} inputBytes
|
* @param {byteArray} inputBytes
|
||||||
* @returns {frequency}
|
* @returns {frequency}
|
||||||
*/
|
*/
|
||||||
calculateByteFrequency(inputBytes) {
|
calculateByteFrequency(inputBytes) {
|
||||||
console.log(inputBytes);
|
const byteFrequency = [];
|
||||||
|
|
||||||
let byteFrequency = [];
|
|
||||||
for (let i = 0; i < 256; i++) {
|
for (let i = 0; i < 256; i++) {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (let byte of inputBytes) {
|
for (const byte of inputBytes) {
|
||||||
if (byte === i) {
|
if (byte === i) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byteFrequency.push(count / (inputBytes.length + 1))
|
byteFrequency.push(count / (inputBytes.length + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return byteFrequency;
|
return byteFrequency;
|
||||||
@ -163,14 +160,12 @@ class AdvancedEntropy extends Operation {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the frequency of bytes in the input.
|
* Calculates the frequency of bytes in the input.
|
||||||
*
|
*
|
||||||
* @param {byteArray} input
|
* @param {byteArray} byteFrequency
|
||||||
* @returns {frequency}
|
* @returns {frequency}
|
||||||
*/
|
*/
|
||||||
createByteFrequencyLineHistogram(entropyData) {
|
createByteFrequencyLineHistogram(byteFrequency) {
|
||||||
const byteFrequency = entropyData.byteFrequency;
|
const margins = { top: 30, right: 20, bottom: 50, left: 30 };
|
||||||
|
|
||||||
const margins = {top: 30, right: 20, bottom: 50, left: 30};
|
|
||||||
|
|
||||||
const svgWidth = 500,
|
const svgWidth = 500,
|
||||||
svgHeight = 500;
|
svgHeight = 500;
|
||||||
@ -192,28 +187,28 @@ class AdvancedEntropy extends Operation {
|
|||||||
.range([margins.left, svgWidth - margins.right]);
|
.range([margins.left, svgWidth - margins.right]);
|
||||||
|
|
||||||
const line = d3.line()
|
const line = d3.line()
|
||||||
.x((d, i) => { return xScale(i)})
|
.x((_, i) => xScale(i))
|
||||||
.y((d) => { return yScale(d)})
|
.y(d => yScale(d))
|
||||||
.curve(d3.curveMonotoneX);
|
.curve(d3.curveMonotoneX);
|
||||||
|
|
||||||
svg.append('path')
|
svg.append("path")
|
||||||
.datum(byteFrequency)
|
.datum(byteFrequency)
|
||||||
.attr("d", line)
|
.attr("d", line)
|
||||||
.attr("fill", "steelblue");
|
.attr("fill", "steelblue");
|
||||||
|
|
||||||
this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "", "Byte", "Byte Frequency");
|
this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "", "Byte", "Byte Frequency");
|
||||||
|
|
||||||
return svg._groups[0][0].outerHTML;
|
return svg._groups[0][0].outerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a byte frequency histogram
|
* Creates a byte frequency histogram
|
||||||
*
|
*
|
||||||
* @param {byteArray} entropyData
|
* @param {byteArray} byteFrequency
|
||||||
* @returns {HTML}
|
* @returns {HTML}
|
||||||
*/
|
*/
|
||||||
createByteFrequencyBarHistogram(entropyData) {
|
createByteFrequencyBarHistogram(byteFrequency) {
|
||||||
const byteFrequency = entropyData.byteFrequency;
|
const margins = { top: 30, right: 20, bottom: 50, left: 30 };
|
||||||
|
|
||||||
const svgWidth = 500,
|
const svgWidth = 500,
|
||||||
svgHeight = 500,
|
svgHeight = 500,
|
||||||
@ -225,8 +220,6 @@ class AdvancedEntropy extends Operation {
|
|||||||
.attr("width", "100%")
|
.attr("width", "100%")
|
||||||
.attr("height", "100%")
|
.attr("height", "100%")
|
||||||
.attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`);
|
.attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`);
|
||||||
|
|
||||||
const margins = {top: 30, right: 20, bottom: 50, left: 30};
|
|
||||||
|
|
||||||
const yScale = d3.scaleLinear()
|
const yScale = d3.scaleLinear()
|
||||||
.domain(d3.extent(byteFrequency, d => d))
|
.domain(d3.extent(byteFrequency, d => d))
|
||||||
@ -240,7 +233,7 @@ class AdvancedEntropy extends Operation {
|
|||||||
.data(byteFrequency)
|
.data(byteFrequency)
|
||||||
.enter().append("rect")
|
.enter().append("rect")
|
||||||
.attr("x", (_, i) => xScale(i) + binWidth)
|
.attr("x", (_, i) => xScale(i) + binWidth)
|
||||||
.attr("y", (dataPoint) => yScale(dataPoint))
|
.attr("y", dataPoint => yScale(dataPoint))
|
||||||
.attr("width", binWidth)
|
.attr("width", binWidth)
|
||||||
.attr("height", dataPoint => yScale(0) - yScale(dataPoint))
|
.attr("height", dataPoint => yScale(0) - yScale(dataPoint))
|
||||||
.attr("fill", "blue");
|
.attr("fill", "blue");
|
||||||
@ -252,13 +245,13 @@ class AdvancedEntropy extends Operation {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a byte frequency histogram
|
* Creates a byte frequency histogram
|
||||||
*
|
*
|
||||||
* @param {byteArray} input
|
* @param {byteArray} input
|
||||||
* @param {number} blockSize
|
* @param {number} blockSize
|
||||||
* @returns {HTML}
|
* @returns {HTML}
|
||||||
*/
|
*/
|
||||||
createEntropyCurve(input) {
|
createEntropyCurve(entropyData) {
|
||||||
const { entropyData, binWidth } = this.calculateScanningEntropy(input);
|
const margins = { top: 30, right: 20, bottom: 50, left: 30 };
|
||||||
|
|
||||||
const svgWidth = 500,
|
const svgWidth = 500,
|
||||||
svgHeight = 500;
|
svgHeight = 500;
|
||||||
@ -270,8 +263,6 @@ class AdvancedEntropy extends Operation {
|
|||||||
.attr("height", "100%")
|
.attr("height", "100%")
|
||||||
.attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`);
|
.attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`);
|
||||||
|
|
||||||
const margins = {top: 30, right: 20, bottom: 50, left: 30};
|
|
||||||
|
|
||||||
const yScale = d3.scaleLinear()
|
const yScale = d3.scaleLinear()
|
||||||
.domain([0, d3.max(entropyData, d => d)])
|
.domain([0, d3.max(entropyData, d => d)])
|
||||||
.range([svgHeight - margins.bottom, margins.top]);
|
.range([svgHeight - margins.bottom, margins.top]);
|
||||||
@ -281,37 +272,35 @@ class AdvancedEntropy extends Operation {
|
|||||||
.range([margins.left, svgWidth - margins.right]);
|
.range([margins.left, svgWidth - margins.right]);
|
||||||
|
|
||||||
const line = d3.line()
|
const line = d3.line()
|
||||||
.x((d, i) => { return xScale(i)})
|
.x((_, i) => xScale(i))
|
||||||
.y((d) => { return yScale(d)})
|
.y(d => yScale(d))
|
||||||
.curve(d3.curveMonotoneX);
|
.curve(d3.curveMonotoneX);
|
||||||
|
|
||||||
if (entropyData.length > 0 ) {
|
if (entropyData.length > 0) {
|
||||||
svg.append('path')
|
svg.append("path")
|
||||||
.datum(entropyData)
|
.datum(entropyData)
|
||||||
.attr("d", line);
|
.attr("d", line);
|
||||||
|
|
||||||
svg.selectAll("path").attr("fill", "none").attr("stroke", "steelblue");
|
svg.selectAll("path").attr("fill", "none").attr("stroke", "steelblue");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "Scanning Entropy" , `Block (${binWidth}B)`, "Entropy");
|
this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "Scanning Entropy", "Block", "Entropy");
|
||||||
|
|
||||||
return svg._groups[0][0].outerHTML;
|
return svg._groups[0][0].outerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an image representation of the entropy
|
* Creates an image representation of the entropy
|
||||||
*
|
*
|
||||||
* @param {byteArray} input
|
* @param {byteArray} input
|
||||||
* @param {number} blockSize
|
* @param {number} blockSize
|
||||||
* @returns {HTML}
|
* @returns {HTML}
|
||||||
*/
|
*/
|
||||||
createEntropyImage(inputBytes) {
|
createEntropyImage(entropyData) {
|
||||||
const svgHeight = 100,
|
const svgHeight = 100,
|
||||||
svgWidth = 100,
|
svgWidth = 100,
|
||||||
cellSize = 1,
|
cellSize = 1,
|
||||||
nodes = [];
|
nodes = [];
|
||||||
|
|
||||||
const { entropyData } = this.calculateScanningEntropy(inputBytes, svgWidth*svgHeight);
|
|
||||||
|
|
||||||
for (let i = 0; i < entropyData.length; i++) {
|
for (let i = 0; i < entropyData.length; i++) {
|
||||||
nodes.push({
|
nodes.push({
|
||||||
@ -337,11 +326,11 @@ class AdvancedEntropy extends Operation {
|
|||||||
.selectAll("rect")
|
.selectAll("rect")
|
||||||
.data(nodes)
|
.data(nodes)
|
||||||
.enter().append("rect")
|
.enter().append("rect")
|
||||||
.attr("x", (d, i) => d.x * cellSize)
|
.attr("x", d => d.x * cellSize)
|
||||||
.attr("y", (d, i) => d.y * cellSize)
|
.attr("y", d => d.y * cellSize)
|
||||||
.attr("width", cellSize)
|
.attr("width", cellSize)
|
||||||
.attr("height", cellSize)
|
.attr("height", cellSize)
|
||||||
.style("fill", (d) => greyScale(d.entropy))
|
.style("fill", d => greyScale(d.entropy));
|
||||||
|
|
||||||
return svg._groups[0][0].outerHTML;
|
return svg._groups[0][0].outerHTML;
|
||||||
}
|
}
|
||||||
@ -351,21 +340,18 @@ class AdvancedEntropy extends Operation {
|
|||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {html}
|
* @returns {html}
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const visualizationType = args[0];
|
const visualizationType = args[0];
|
||||||
|
|
||||||
const entropyData = {
|
if (visualizationType === "Histogram (Bar)") {
|
||||||
entropy: this.calculateShannonEntropy(input),
|
return this.createByteFrequencyBarHistogram(this.calculateByteFrequency(input));
|
||||||
byteFrequency: this.calculateByteFrequency(input)
|
} else if (visualizationType === "Histogram (Line)") {
|
||||||
};
|
return this.createByteFrequencyLineHistogram(this.calculateByteFrequency(input));
|
||||||
|
} else if (visualizationType === "Curve") {
|
||||||
let svgData;
|
return this.createEntropyCurve(this.calculateScanningEntropy(input).entropyData);
|
||||||
if (visualizationType === "Histogram (Bar)") svgData = this.createByteFrequencyBarHistogram(entropyData);
|
} else if (visualizationType === "Image") {
|
||||||
else if (visualizationType === "Histogram (Line)") svgData = this.createByteFrequencyLineHistogram(entropyData);
|
return this.createEntropyImage(this.calculateScanningEntropy(input, 10000).entropyData);
|
||||||
else if (visualizationType === "Curve") svgData = this.createEntropyCurve(input);
|
}
|
||||||
else if (visualizationType === "Image") svgData = this.createEntropyImage(input);
|
|
||||||
|
|
||||||
return svgData;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user