Skip to content

Commit 75a28b5

Browse files
authored
Merge pull request #1762 from gchq/feature/floats
2 parents b88fbcc + 6efa2dd commit 75a28b5

7 files changed

Lines changed: 327 additions & 0 deletions

File tree

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
"escodegen": "^2.1.0",
123123
"esprima": "^4.0.1",
124124
"exif-parser": "^0.1.12",
125+
"ieee754": "^1.1.13",
125126
"fernet": "^0.3.2",
126127
"file-saver": "^2.0.5",
127128
"flat": "^6.0.1",

src/core/config/Categories.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"From Charcode",
1515
"To Decimal",
1616
"From Decimal",
17+
"To Float",
18+
"From Float",
1719
"To Binary",
1820
"From Binary",
1921
"To Octal",

src/core/operations/FromFloat.mjs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* @author tcode2k16 [tcode2k16@gmail.com]
3+
* @copyright Crown Copyright 2019
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import Utils from "../Utils.mjs";
9+
import ieee754 from "ieee754";
10+
import {DELIM_OPTIONS} from "../lib/Delim.mjs";
11+
12+
/**
13+
* From Float operation
14+
*/
15+
class FromFloat extends Operation {
16+
17+
/**
18+
* FromFloat constructor
19+
*/
20+
constructor() {
21+
super();
22+
23+
this.name = "From Float";
24+
this.module = "Default";
25+
this.description = "Convert from EEE754 Floating Point Numbers";
26+
this.infoURL = "https://en.wikipedia.org/wiki/IEEE_754";
27+
this.inputType = "string";
28+
this.outputType = "byteArray";
29+
this.args = [
30+
{
31+
"name": "Endianness",
32+
"type": "option",
33+
"value": [
34+
"Big Endian",
35+
"Little Endian"
36+
]
37+
},
38+
{
39+
"name": "Size",
40+
"type": "option",
41+
"value": [
42+
"Float (4 bytes)",
43+
"Double (8 bytes)"
44+
]
45+
},
46+
{
47+
"name": "Delimiter",
48+
"type": "option",
49+
"value": DELIM_OPTIONS
50+
}
51+
];
52+
}
53+
54+
/**
55+
* @param {string} input
56+
* @param {Object[]} args
57+
* @returns {byteArray}
58+
*/
59+
run(input, args) {
60+
if (input.length === 0) return [];
61+
62+
const [endianness, size, delimiterName] = args;
63+
const delim = Utils.charRep(delimiterName || "Space");
64+
const byteSize = size === "Double (8 bytes)" ? 8 : 4;
65+
const isLE = endianness === "Little Endian";
66+
const mLen = byteSize === 4 ? 23 : 52;
67+
const floats = input.split(delim);
68+
69+
const output = new Array(floats.length*byteSize);
70+
for (let i = 0; i < floats.length; i++) {
71+
ieee754.write(output, parseFloat(floats[i]), i*byteSize, isLE, mLen, byteSize);
72+
}
73+
return output;
74+
}
75+
76+
}
77+
78+
export default FromFloat;

src/core/operations/ToFloat.mjs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* @author tcode2k16 [tcode2k16@gmail.com]
3+
* @copyright Crown Copyright 2019
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import OperationError from "../errors/OperationError.mjs";
9+
import Utils from "../Utils.mjs";
10+
import ieee754 from "ieee754";
11+
import {DELIM_OPTIONS} from "../lib/Delim.mjs";
12+
13+
/**
14+
* To Float operation
15+
*/
16+
class ToFloat extends Operation {
17+
18+
/**
19+
* ToFloat constructor
20+
*/
21+
constructor() {
22+
super();
23+
24+
this.name = "To Float";
25+
this.module = "Default";
26+
this.description = "Convert to EEE754 Floating Point Numbers";
27+
this.infoURL = "https://en.wikipedia.org/wiki/IEEE_754";
28+
this.inputType = "byteArray";
29+
this.outputType = "string";
30+
this.args = [
31+
{
32+
"name": "Endianness",
33+
"type": "option",
34+
"value": [
35+
"Big Endian",
36+
"Little Endian"
37+
]
38+
},
39+
{
40+
"name": "Size",
41+
"type": "option",
42+
"value": [
43+
"Float (4 bytes)",
44+
"Double (8 bytes)"
45+
]
46+
},
47+
{
48+
"name": "Delimiter",
49+
"type": "option",
50+
"value": DELIM_OPTIONS
51+
}
52+
];
53+
}
54+
55+
/**
56+
* @param {byteArray} input
57+
* @param {Object[]} args
58+
* @returns {string}
59+
*/
60+
run(input, args) {
61+
const [endianness, size, delimiterName] = args;
62+
const delim = Utils.charRep(delimiterName || "Space");
63+
const byteSize = size === "Double (8 bytes)" ? 8 : 4;
64+
const isLE = endianness === "Little Endian";
65+
const mLen = byteSize === 4 ? 23 : 52;
66+
67+
if (input.length % byteSize !== 0) {
68+
throw new OperationError(`Input is not a multiple of ${byteSize}`);
69+
}
70+
71+
const output = [];
72+
for (let i = 0; i < input.length; i+=byteSize) {
73+
output.push(ieee754.read(input, i, isLE, mLen, byteSize));
74+
}
75+
return output.join(delim);
76+
}
77+
78+
}
79+
80+
export default ToFloat;

tests/operations/index.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import "./tests/DefangIP.mjs";
6262
import "./tests/ELFInfo.mjs";
6363
import "./tests/Enigma.mjs";
6464
import "./tests/ExtractEmailAddresses.mjs";
65+
import "./tests/Float.mjs";
6566
import "./tests/FileTree.mjs";
6667
import "./tests/FletcherChecksum.mjs";
6768
import "./tests/Fork.mjs";

tests/operations/tests/Float.mjs

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* Float tests.
3+
*
4+
* @author tcode2k16 [tcode2k16@gmail.com]
5+
*
6+
* @copyright Crown Copyright 2019
7+
* @license Apache-2.0
8+
*/
9+
10+
import TestRegister from "../../lib/TestRegister.mjs";
11+
12+
13+
TestRegister.addTests([
14+
{
15+
name: "To Float: nothing",
16+
input: "",
17+
expectedOutput: "",
18+
recipeConfig: [
19+
{
20+
op: "From Hex",
21+
args: ["Auto"]
22+
},
23+
{
24+
op: "To Float",
25+
args: ["Big Endian", "Float (4 bytes)", "Space"]
26+
}
27+
],
28+
},
29+
{
30+
name: "To Float (Big Endian, 4 bytes): 0.5",
31+
input: "3f0000003f000000",
32+
expectedOutput: "0.5 0.5",
33+
recipeConfig: [
34+
{
35+
op: "From Hex",
36+
args: ["Auto"]
37+
},
38+
{
39+
op: "To Float",
40+
args: ["Big Endian", "Float (4 bytes)", "Space"]
41+
}
42+
]
43+
},
44+
{
45+
name: "To Float (Little Endian, 4 bytes): 0.5",
46+
input: "0000003f0000003f",
47+
expectedOutput: "0.5 0.5",
48+
recipeConfig: [
49+
{
50+
op: "From Hex",
51+
args: ["Auto"]
52+
},
53+
{
54+
op: "To Float",
55+
args: ["Little Endian", "Float (4 bytes)", "Space"]
56+
}
57+
]
58+
},
59+
{
60+
name: "To Float (Big Endian, 8 bytes): 0.5",
61+
input: "3fe00000000000003fe0000000000000",
62+
expectedOutput: "0.5 0.5",
63+
recipeConfig: [
64+
{
65+
op: "From Hex",
66+
args: ["Auto"]
67+
},
68+
{
69+
op: "To Float",
70+
args: ["Big Endian", "Double (8 bytes)", "Space"]
71+
}
72+
]
73+
},
74+
{
75+
name: "To Float (Little Endian, 8 bytes): 0.5",
76+
input: "000000000000e03f000000000000e03f",
77+
expectedOutput: "0.5 0.5",
78+
recipeConfig: [
79+
{
80+
op: "From Hex",
81+
args: ["Auto"]
82+
},
83+
{
84+
op: "To Float",
85+
args: ["Little Endian", "Double (8 bytes)", "Space"]
86+
}
87+
]
88+
},
89+
{
90+
name: "From Float: nothing",
91+
input: "",
92+
expectedOutput: "",
93+
recipeConfig: [
94+
{
95+
op: "From Float",
96+
args: ["Big Endian", "Float (4 bytes)", "Space"]
97+
},
98+
{
99+
op: "To Hex",
100+
args: ["None"]
101+
}
102+
]
103+
},
104+
{
105+
name: "From Float (Big Endian, 4 bytes): 0.5",
106+
input: "0.5 0.5",
107+
expectedOutput: "3f0000003f000000",
108+
recipeConfig: [
109+
{
110+
op: "From Float",
111+
args: ["Big Endian", "Float (4 bytes)", "Space"]
112+
},
113+
{
114+
op: "To Hex",
115+
args: ["None"]
116+
}
117+
]
118+
},
119+
{
120+
name: "From Float (Little Endian, 4 bytes): 0.5",
121+
input: "0.5 0.5",
122+
expectedOutput: "0000003f0000003f",
123+
recipeConfig: [
124+
{
125+
op: "From Float",
126+
args: ["Little Endian", "Float (4 bytes)", "Space"]
127+
},
128+
{
129+
op: "To Hex",
130+
args: ["None"]
131+
}
132+
]
133+
},
134+
{
135+
name: "From Float (Big Endian, 8 bytes): 0.5",
136+
input: "0.5 0.5",
137+
expectedOutput: "3fe00000000000003fe0000000000000",
138+
recipeConfig: [
139+
{
140+
op: "From Float",
141+
args: ["Big Endian", "Double (8 bytes)", "Space"]
142+
},
143+
{
144+
op: "To Hex",
145+
args: ["None"]
146+
}
147+
]
148+
},
149+
{
150+
name: "From Float (Little Endian, 8 bytes): 0.5",
151+
input: "0.5 0.5",
152+
expectedOutput: "000000000000e03f000000000000e03f",
153+
recipeConfig: [
154+
{
155+
op: "From Float",
156+
args: ["Little Endian", "Double (8 bytes)", "Space"]
157+
},
158+
{
159+
op: "To Hex",
160+
args: ["None"]
161+
}
162+
]
163+
}
164+
]);

0 commit comments

Comments
 (0)