Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31a4eef001 | ||
|
|
d6e2c9a6b9 | ||
|
|
e069f5db13 | ||
|
|
96b59cf0df | ||
|
|
c1e1d4b7e3 | ||
|
|
32d869231e | ||
|
|
6f95f01dda | ||
|
|
61a1c44f26 | ||
|
|
e6c7899569 | ||
|
|
a74a14145e | ||
|
|
04022b22be | ||
|
|
4f3010691c | ||
|
|
672b477751 | ||
|
|
19360391a6 | ||
|
|
447be8af34 | ||
|
|
0989550e5c | ||
|
|
4d9b48b4d8 | ||
|
|
979652387d | ||
|
|
de84fbdd1c | ||
|
|
170e564319 | ||
|
|
7526f4d7b1 | ||
|
|
cd8a85975c | ||
|
|
2f94ec20b0 | ||
|
|
09d9deae43 | ||
|
|
2e0af64ac3 | ||
|
|
30bc8dfbe9 | ||
|
|
53a579028c |
No files matched your search
@@ -1,4 +1,4 @@
|
||||
name: "CodeQL"
|
||||
name: "CodeQL Analysis"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Master
|
||||
name: "Master Build, Test & Deploy"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: PRs
|
||||
name: "Pull Requests"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Release
|
||||
name: "Releases"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -13,6 +13,12 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
## Details
|
||||
|
||||
### [9.26.0] - 2021-02-11
|
||||
- 'Get Time' operation added [@n1073645] [@n1474335] | [#1045]
|
||||
|
||||
### [9.25.0] - 2021-02-11
|
||||
- 'Extract ID3' operation added [@n1073645] [@n1474335] | [#1006]
|
||||
|
||||
### [9.24.0] - 2021-02-02
|
||||
- 'SM3' hashing function added along with more configuration options for other hashing operations [@n1073645] [@n1474335] | [#1022]
|
||||
|
||||
@@ -247,6 +253,8 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
|
||||
|
||||
[9.26.0]: https://github.com/gchq/CyberChef/releases/tag/v9.26.0
|
||||
[9.25.0]: https://github.com/gchq/CyberChef/releases/tag/v9.25.0
|
||||
[9.24.0]: https://github.com/gchq/CyberChef/releases/tag/v9.24.0
|
||||
[9.23.0]: https://github.com/gchq/CyberChef/releases/tag/v9.23.0
|
||||
[9.22.0]: https://github.com/gchq/CyberChef/releases/tag/v9.22.0
|
||||
@@ -424,6 +432,8 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[#965]: https://github.com/gchq/CyberChef/pull/965
|
||||
[#966]: https://github.com/gchq/CyberChef/pull/966
|
||||
[#987]: https://github.com/gchq/CyberChef/pull/987
|
||||
[#1006]: https://github.com/gchq/CyberChef/pull/1006
|
||||
[#1022]: https://github.com/gchq/CyberChef/pull/1022
|
||||
[#1045]: https://github.com/gchq/CyberChef/pull/1045
|
||||
[#1049]: https://github.com/gchq/CyberChef/pull/1049
|
||||
[#1083]: https://github.com/gchq/CyberChef/pull/1083
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.24.7",
|
||||
"version": "9.26.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.24.7",
|
||||
"version": "9.26.1",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
|
||||
+20
-2
@@ -170,13 +170,18 @@ class Utils {
|
||||
*
|
||||
* @param {string} str - The input string to display.
|
||||
* @param {boolean} [preserveWs=false] - Whether or not to print whitespace.
|
||||
* @param {boolean} [onlyAscii=false] - Whether or not to replace non ASCII characters.
|
||||
* @returns {string}
|
||||
*/
|
||||
static printable(str, preserveWs=false) {
|
||||
static printable(str, preserveWs=false, onlyAscii=false) {
|
||||
if (isWebEnvironment() && window.app && !window.app.options.treatAsUtf8) {
|
||||
str = Utils.byteArrayToChars(Utils.strToByteArray(str));
|
||||
}
|
||||
|
||||
if (onlyAscii) {
|
||||
return str.replace(/[^\x20-\x7f]/g, ".");
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-misleading-character-class
|
||||
const re = /[\0-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF]/g;
|
||||
const wsRe = /[\x09-\x10\x0D\u2028\u2029]/g;
|
||||
@@ -704,8 +709,21 @@ class Utils {
|
||||
* Utils.stripHtmlTags("<div>Test</div>");
|
||||
*/
|
||||
static stripHtmlTags(htmlStr, removeScriptAndStyle=false) {
|
||||
/**
|
||||
* Recursively remove a pattern from a string until there are no more matches.
|
||||
* Avoids incomplete sanitization e.g. "aabcbc".replace(/abc/g, "") === "abc"
|
||||
*
|
||||
* @param {RegExp} pattern
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
function recursiveRemove(pattern, str) {
|
||||
const newStr = str.replace(pattern, "");
|
||||
return newStr.length === str.length ? newStr : recursiveRemove(pattern, newStr);
|
||||
}
|
||||
|
||||
if (removeScriptAndStyle) {
|
||||
htmlStr = htmlStr.replace(/<(script|style)[^>]*>.*?<\/(script|style)>/gi, "");
|
||||
htmlStr = recursiveRemove(/<(script|style)[^>]*>.*?<\/(script|style)>/gi, htmlStr);
|
||||
}
|
||||
return htmlStr.replace(/<[^>]+>/g, "");
|
||||
}
|
||||
|
||||
@@ -267,6 +267,7 @@
|
||||
"Windows Filetime to UNIX Timestamp",
|
||||
"UNIX Timestamp to Windows Filetime",
|
||||
"Extract dates",
|
||||
"Get Time",
|
||||
"Sleep"
|
||||
]
|
||||
},
|
||||
@@ -286,6 +287,7 @@
|
||||
"JPath expression",
|
||||
"CSS selector",
|
||||
"Extract EXIF",
|
||||
"Extract ID3",
|
||||
"Extract Files"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -2197,14 +2197,14 @@ export const FILE_SIGNATURES = {
|
||||
mime: "application/octet-stream",
|
||||
description: "",
|
||||
signature: {
|
||||
0: 0x6b, // keych
|
||||
0: 0x6b, // kych
|
||||
1: 0x79,
|
||||
2: 0x63,
|
||||
3: 0x68,
|
||||
4: 0x00,
|
||||
5: 0x01
|
||||
},
|
||||
extractor: null
|
||||
extractor: extractMacOSXKeychain
|
||||
},
|
||||
{
|
||||
name: "TCP Packet",
|
||||
@@ -2355,6 +2355,12 @@ export const FILE_SIGNATURES = {
|
||||
1: 0x03,
|
||||
2: 0xc6,
|
||||
3: 0x04
|
||||
},
|
||||
{
|
||||
0: 0x95,
|
||||
1: 0x05,
|
||||
2: 0x86,
|
||||
3: 0x04
|
||||
}
|
||||
],
|
||||
extractor: null
|
||||
@@ -3406,6 +3412,26 @@ export function extractPListXML(bytes, offset) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MacOS X Keychain Extactor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractMacOSXKeychain(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Move to size field.
|
||||
stream.moveTo(0x14);
|
||||
|
||||
// Move forwards by size.
|
||||
stream.moveForwardsBy(stream.readInt(4));
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OLE2 extractor.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/**
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* Extract ID3 operation
|
||||
*/
|
||||
class ExtractID3 extends Operation {
|
||||
|
||||
/**
|
||||
* ExtractID3 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Extract ID3";
|
||||
this.module = "Default";
|
||||
this.description = "This operation extracts ID3 metadata from an MP3 file.<br><br>ID3 is a metadata container most often used in conjunction with the MP3 audio file format. It allows information such as the title, artist, album, track number, and other information about the file to be stored in the file itself.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/ID3";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "JSON";
|
||||
this.presentType = "html";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {JSON}
|
||||
*/
|
||||
run(input, args) {
|
||||
input = new Uint8Array(input);
|
||||
|
||||
/**
|
||||
* Extracts the ID3 header fields.
|
||||
*/
|
||||
function extractHeader() {
|
||||
if (!Array.from(input.slice(0, 3)).equals([0x49, 0x44, 0x33]))
|
||||
throw new OperationError("No valid ID3 header.");
|
||||
|
||||
const header = {
|
||||
"Type": "ID3",
|
||||
// Tag version
|
||||
"Version": input[3].toString() + "." + input[4].toString(),
|
||||
// Header version
|
||||
"Flags": input[5].toString()
|
||||
};
|
||||
|
||||
input = input.slice(6);
|
||||
return header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the size fields to a single integer.
|
||||
*
|
||||
* @param {number} num
|
||||
* @returns {string}
|
||||
*/
|
||||
function readSize(num) {
|
||||
let result = 0;
|
||||
|
||||
// The sizes are 7 bit numbers stored in 8 bit locations
|
||||
for (let i = (num) * 7; i; i -= 7) {
|
||||
result = (result << i) | input[0];
|
||||
input = input.slice(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads frame header based on ID.
|
||||
*
|
||||
* @param {string} id
|
||||
* @returns {number}
|
||||
*/
|
||||
function readFrame(id) {
|
||||
const frame = {};
|
||||
|
||||
// Size of frame
|
||||
const size = readSize(4);
|
||||
frame.Size = size.toString();
|
||||
frame.Description = FRAME_DESCRIPTIONS[id];
|
||||
input = input.slice(2);
|
||||
|
||||
// Read data from frame
|
||||
let data = "";
|
||||
for (let i = 1; i < size; i++)
|
||||
data += String.fromCharCode(input[i]);
|
||||
frame.Data = data;
|
||||
|
||||
// Move to next Frame
|
||||
input = input.slice(size);
|
||||
|
||||
return [frame, size];
|
||||
}
|
||||
|
||||
const result = extractHeader();
|
||||
|
||||
const headerTagSize = readSize(4);
|
||||
result.Size = headerTagSize.toString();
|
||||
|
||||
const tags = {};
|
||||
let pos = 10;
|
||||
|
||||
// While the current element is in the header
|
||||
while (pos < headerTagSize) {
|
||||
|
||||
// Frame Identifier of frame
|
||||
let id = String.fromCharCode(input[0]) + String.fromCharCode(input[1]) + String.fromCharCode(input[2]);
|
||||
input = input.slice(3);
|
||||
|
||||
// If the next character is non-zero it is an identifier
|
||||
if (input[0] !== 0) {
|
||||
id += String.fromCharCode(input[0]);
|
||||
}
|
||||
input = input.slice(1);
|
||||
|
||||
if (id in FRAME_DESCRIPTIONS) {
|
||||
const [frame, size] = readFrame(id);
|
||||
tags[id] = frame;
|
||||
pos += 10 + size;
|
||||
} else if (id === "\x00\x00\x00") { // end of header
|
||||
break;
|
||||
} else {
|
||||
throw new OperationError("Unknown Frame Identifier: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
result.Tags = tags;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the extracted data in a more accessible format for web apps.
|
||||
* @param {JSON} data
|
||||
* @returns {html}
|
||||
*/
|
||||
present(data) {
|
||||
if (!data || !Object.prototype.hasOwnProperty.call(data, "Tags"))
|
||||
return JSON.stringify(data, null, 4);
|
||||
|
||||
let output = `<table class="table table-hover table-sm table-bordered table-nonfluid">
|
||||
<tr><th>Tag</th><th>Description</th><th>Data</th></tr>`;
|
||||
|
||||
for (const tagID in data.Tags) {
|
||||
const description = data.Tags[tagID].Description,
|
||||
contents = data.Tags[tagID].Data;
|
||||
output += `<tr><td>${tagID}</td><td>${Utils.escapeHtml(description)}</td><td>${Utils.escapeHtml(contents)}</td></tr>`;
|
||||
}
|
||||
output += "</table>";
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Borrowed from https://github.com/aadsm/jsmediatags
|
||||
const FRAME_DESCRIPTIONS = {
|
||||
// v2.2
|
||||
"BUF": "Recommended buffer size",
|
||||
"CNT": "Play counter",
|
||||
"COM": "Comments",
|
||||
"CRA": "Audio encryption",
|
||||
"CRM": "Encrypted meta frame",
|
||||
"ETC": "Event timing codes",
|
||||
"EQU": "Equalization",
|
||||
"GEO": "General encapsulated object",
|
||||
"IPL": "Involved people list",
|
||||
"LNK": "Linked information",
|
||||
"MCI": "Music CD Identifier",
|
||||
"MLL": "MPEG location lookup table",
|
||||
"PIC": "Attached picture",
|
||||
"POP": "Popularimeter",
|
||||
"REV": "Reverb",
|
||||
"RVA": "Relative volume adjustment",
|
||||
"SLT": "Synchronized lyric/text",
|
||||
"STC": "Synced tempo codes",
|
||||
"TAL": "Album/Movie/Show title",
|
||||
"TBP": "BPM (Beats Per Minute)",
|
||||
"TCM": "Composer",
|
||||
"TCO": "Content type",
|
||||
"TCR": "Copyright message",
|
||||
"TDA": "Date",
|
||||
"TDY": "Playlist delay",
|
||||
"TEN": "Encoded by",
|
||||
"TFT": "File type",
|
||||
"TIM": "Time",
|
||||
"TKE": "Initial key",
|
||||
"TLA": "Language(s)",
|
||||
"TLE": "Length",
|
||||
"TMT": "Media type",
|
||||
"TOA": "Original artist(s)/performer(s)",
|
||||
"TOF": "Original filename",
|
||||
"TOL": "Original Lyricist(s)/text writer(s)",
|
||||
"TOR": "Original release year",
|
||||
"TOT": "Original album/Movie/Show title",
|
||||
"TP1": "Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group",
|
||||
"TP2": "Band/Orchestra/Accompaniment",
|
||||
"TP3": "Conductor/Performer refinement",
|
||||
"TP4": "Interpreted, remixed, or otherwise modified by",
|
||||
"TPA": "Part of a set",
|
||||
"TPB": "Publisher",
|
||||
"TRC": "ISRC (International Standard Recording Code)",
|
||||
"TRD": "Recording dates",
|
||||
"TRK": "Track number/Position in set",
|
||||
"TSI": "Size",
|
||||
"TSS": "Software/hardware and settings used for encoding",
|
||||
"TT1": "Content group description",
|
||||
"TT2": "Title/Songname/Content description",
|
||||
"TT3": "Subtitle/Description refinement",
|
||||
"TXT": "Lyricist/text writer",
|
||||
"TXX": "User defined text information frame",
|
||||
"TYE": "Year",
|
||||
"UFI": "Unique file identifier",
|
||||
"ULT": "Unsychronized lyric/text transcription",
|
||||
"WAF": "Official audio file webpage",
|
||||
"WAR": "Official artist/performer webpage",
|
||||
"WAS": "Official audio source webpage",
|
||||
"WCM": "Commercial information",
|
||||
"WCP": "Copyright/Legal information",
|
||||
"WPB": "Publishers official webpage",
|
||||
"WXX": "User defined URL link frame",
|
||||
// v2.3
|
||||
"AENC": "Audio encryption",
|
||||
"APIC": "Attached picture",
|
||||
"ASPI": "Audio seek point index",
|
||||
"CHAP": "Chapter",
|
||||
"CTOC": "Table of contents",
|
||||
"COMM": "Comments",
|
||||
"COMR": "Commercial frame",
|
||||
"ENCR": "Encryption method registration",
|
||||
"EQU2": "Equalisation (2)",
|
||||
"EQUA": "Equalization",
|
||||
"ETCO": "Event timing codes",
|
||||
"GEOB": "General encapsulated object",
|
||||
"GRID": "Group identification registration",
|
||||
"IPLS": "Involved people list",
|
||||
"LINK": "Linked information",
|
||||
"MCDI": "Music CD identifier",
|
||||
"MLLT": "MPEG location lookup table",
|
||||
"OWNE": "Ownership frame",
|
||||
"PRIV": "Private frame",
|
||||
"PCNT": "Play counter",
|
||||
"POPM": "Popularimeter",
|
||||
"POSS": "Position synchronisation frame",
|
||||
"RBUF": "Recommended buffer size",
|
||||
"RVA2": "Relative volume adjustment (2)",
|
||||
"RVAD": "Relative volume adjustment",
|
||||
"RVRB": "Reverb",
|
||||
"SEEK": "Seek frame",
|
||||
"SYLT": "Synchronized lyric/text",
|
||||
"SYTC": "Synchronized tempo codes",
|
||||
"TALB": "Album/Movie/Show title",
|
||||
"TBPM": "BPM (beats per minute)",
|
||||
"TCOM": "Composer",
|
||||
"TCON": "Content type",
|
||||
"TCOP": "Copyright message",
|
||||
"TDAT": "Date",
|
||||
"TDLY": "Playlist delay",
|
||||
"TDRC": "Recording time",
|
||||
"TDRL": "Release time",
|
||||
"TDTG": "Tagging time",
|
||||
"TENC": "Encoded by",
|
||||
"TEXT": "Lyricist/Text writer",
|
||||
"TFLT": "File type",
|
||||
"TIME": "Time",
|
||||
"TIPL": "Involved people list",
|
||||
"TIT1": "Content group description",
|
||||
"TIT2": "Title/songname/content description",
|
||||
"TIT3": "Subtitle/Description refinement",
|
||||
"TKEY": "Initial key",
|
||||
"TLAN": "Language(s)",
|
||||
"TLEN": "Length",
|
||||
"TMCL": "Musician credits list",
|
||||
"TMED": "Media type",
|
||||
"TMOO": "Mood",
|
||||
"TOAL": "Original album/movie/show title",
|
||||
"TOFN": "Original filename",
|
||||
"TOLY": "Original lyricist(s)/text writer(s)",
|
||||
"TOPE": "Original artist(s)/performer(s)",
|
||||
"TORY": "Original release year",
|
||||
"TOWN": "File owner/licensee",
|
||||
"TPE1": "Lead performer(s)/Soloist(s)",
|
||||
"TPE2": "Band/orchestra/accompaniment",
|
||||
"TPE3": "Conductor/performer refinement",
|
||||
"TPE4": "Interpreted, remixed, or otherwise modified by",
|
||||
"TPOS": "Part of a set",
|
||||
"TPRO": "Produced notice",
|
||||
"TPUB": "Publisher",
|
||||
"TRCK": "Track number/Position in set",
|
||||
"TRDA": "Recording dates",
|
||||
"TRSN": "Internet radio station name",
|
||||
"TRSO": "Internet radio station owner",
|
||||
"TSOA": "Album sort order",
|
||||
"TSOP": "Performer sort order",
|
||||
"TSOT": "Title sort order",
|
||||
"TSIZ": "Size",
|
||||
"TSRC": "ISRC (international standard recording code)",
|
||||
"TSSE": "Software/Hardware and settings used for encoding",
|
||||
"TSST": "Set subtitle",
|
||||
"TYER": "Year",
|
||||
"TXXX": "User defined text information frame",
|
||||
"UFID": "Unique file identifier",
|
||||
"USER": "Terms of use",
|
||||
"USLT": "Unsychronized lyric/text transcription",
|
||||
"WCOM": "Commercial information",
|
||||
"WCOP": "Copyright/Legal information",
|
||||
"WOAF": "Official audio file webpage",
|
||||
"WOAR": "Official artist/performer webpage",
|
||||
"WOAS": "Official audio source webpage",
|
||||
"WORS": "Official internet radio station homepage",
|
||||
"WPAY": "Payment",
|
||||
"WPUB": "Publishers official webpage",
|
||||
"WXXX": "User defined URL link frame"
|
||||
};
|
||||
|
||||
export default ExtractID3;
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import {UNITS} from "../lib/DateTime.mjs";
|
||||
|
||||
/**
|
||||
* Get Time operation
|
||||
*/
|
||||
class GetTime extends Operation {
|
||||
|
||||
/**
|
||||
* GetTime constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Get Time";
|
||||
this.module = "Default";
|
||||
this.description = "Generates a timestamp showing the amount of time since the UNIX epoch (1970-01-01 00:00:00 UTC). Uses the W3C High Resolution Time API.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Unix_time";
|
||||
this.inputType = "string";
|
||||
this.outputType = "number";
|
||||
this.args = [
|
||||
{
|
||||
name: "Granularity",
|
||||
type: "option",
|
||||
value: UNITS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
*/
|
||||
run(input, args) {
|
||||
const nowMs = (performance.timeOrigin + performance.now()),
|
||||
granularity = args[0];
|
||||
|
||||
switch (granularity) {
|
||||
case "Nanoseconds (ns)":
|
||||
return Math.round(nowMs * 1000 * 1000);
|
||||
case "Microseconds (μs)":
|
||||
return Math.round(nowMs * 1000);
|
||||
case "Milliseconds (ms)":
|
||||
return Math.round(nowMs);
|
||||
case "Seconds (s)":
|
||||
return Math.round(nowMs / 1000);
|
||||
default:
|
||||
throw new OperationError("Unknown granularity value: " + granularity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GetTime;
|
||||
@@ -20,7 +20,7 @@ class ToHexdump extends Operation {
|
||||
|
||||
this.name = "To Hexdump";
|
||||
this.module = "Default";
|
||||
this.description = "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.";
|
||||
this.description = "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.<br><br>The 'UNIX format' argument defines which subset of printable characters are displayed in the preview column.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Hex_dump";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
@@ -39,6 +39,11 @@ class ToHexdump extends Operation {
|
||||
"name": "Include final length",
|
||||
"type": "boolean",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"name": "UNIX format",
|
||||
"type": "boolean",
|
||||
"value": false
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -50,7 +55,7 @@ class ToHexdump extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const data = new Uint8Array(input);
|
||||
const [length, upperCase, includeFinalLength] = args;
|
||||
const [length, upperCase, includeFinalLength, unixFormat] = args;
|
||||
const padding = 2;
|
||||
|
||||
let output = "";
|
||||
@@ -70,7 +75,9 @@ class ToHexdump extends Operation {
|
||||
|
||||
output += lineNo + " " +
|
||||
hexa.padEnd(length*(padding+1), " ") +
|
||||
" |" + Utils.printable(Utils.byteArrayToChars(buff)).padEnd(buff.length, " ") + "|\n";
|
||||
" |" +
|
||||
Utils.printable(Utils.byteArrayToChars(buff), false, unixFormat).padEnd(buff.length, " ") +
|
||||
"|\n";
|
||||
|
||||
if (includeFinalLength && i+buff.length === data.length) {
|
||||
output += Utils.hex(i+buff.length, 8) + "\n";
|
||||
|
||||
+20
-12
@@ -6,6 +6,7 @@
|
||||
|
||||
import HTMLIngredient from "./HTMLIngredient.mjs";
|
||||
import Utils from "../core/Utils.mjs";
|
||||
import url from "url";
|
||||
|
||||
|
||||
/**
|
||||
@@ -147,22 +148,29 @@ class HTMLOperation {
|
||||
/**
|
||||
* Given a URL for a Wikipedia (or other wiki) page, this function returns a link to that page.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {string} urlStr
|
||||
* @returns {string}
|
||||
*/
|
||||
function titleFromWikiLink(url) {
|
||||
const splitURL = url.split("/");
|
||||
if (!splitURL.includes("wikipedia.org") && !splitURL.includes("forensicswiki.xyz")) {
|
||||
// Not a wiki link, return full URL
|
||||
return `<a href='${url}' target='_blank'>More Information<i class='material-icons inline-icon'>open_in_new</i></a>`;
|
||||
function titleFromWikiLink(urlStr) {
|
||||
const urlObj = url.parse(urlStr);
|
||||
let wikiName = "",
|
||||
pageTitle = "";
|
||||
|
||||
switch (urlObj.host) {
|
||||
case "forensicswiki.xyz":
|
||||
wikiName = "Forensics Wiki";
|
||||
pageTitle = urlObj.query.substr(6).replace(/_/g, " "); // Chop off 'title='
|
||||
break;
|
||||
case "wikipedia.org":
|
||||
wikiName = "Wikipedia";
|
||||
pageTitle = urlObj.pathname.substr(6).replace(/_/g, " "); // Chop off '/wiki/'
|
||||
break;
|
||||
default:
|
||||
// Not a wiki link, return full URL
|
||||
return `<a href='${urlStr}' target='_blank'>More Information<i class='material-icons inline-icon'>open_in_new</i></a>`;
|
||||
}
|
||||
|
||||
const wikiName = splitURL.includes("forensicswiki.xyz") ? "Forensics Wiki" : "Wikipedia";
|
||||
|
||||
const pageTitle = decodeURIComponent(splitURL[splitURL.length - 1])
|
||||
.replace(/_/g, " ")
|
||||
.replace(/index\.php\?title=/g, "");
|
||||
return `<a href='${url}' target='_blank'>${pageTitle}<i class='material-icons inline-icon'>open_in_new</i></a> on ${wikiName}`;
|
||||
return `<a href='${urlObj.href}' target='_blank'>${pageTitle}<i class='material-icons inline-icon'>open_in_new</i></a> on ${wikiName}`;
|
||||
}
|
||||
|
||||
export default HTMLOperation;
|
||||
Reference in new issue
Block a user