This commit is contained in:
kossithedon 2025-04-14 03:39:17 +00:00 committed by GitHub
commit aaff64fb10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 654 additions and 0 deletions

View file

@ -348,6 +348,8 @@
"To UNIX Timestamp", "To UNIX Timestamp",
"Windows Filetime to UNIX Timestamp", "Windows Filetime to UNIX Timestamp",
"UNIX Timestamp to Windows Filetime", "UNIX Timestamp to Windows Filetime",
"NTP Timestamp to UNIX Timestamp",
"UNIX Timestamp to NTP Timestamp",
"DateTime Delta", "DateTime Delta",
"Extract dates", "Extract dates",
"Get Time", "Get Time",

View file

@ -0,0 +1,135 @@
/**
* @author kossithedon [kossivijunior@yahoo.fr]
* @copyright Crown Copyright 2024
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import BigNumber from "bignumber.js";
import OperationError from "../errors/OperationError.mjs";
import RemoveWhitespace from "./RemoveWhitespace.mjs";
import SwapEndianness from "./SwapEndianness.mjs";
/**
* NTP Timestamp to UNIX Timestamp operation
*/
class NTPTimestampToUNIXTimestamp extends Operation {
/**
* NTPTimestampToUNIXTimestamp constructor
*/
constructor() {
super();
this.name = "NTP Timestamp to UNIX Timestamp";
this.module = "Default";
this.description = "Convert an NTP timestamp to the corresponding UNIX timestamp.<br><br>An NTP timestamp is a 64-bit value representing time in the Network Time Protocol (NTP).<br><br>The NTP timestamp is in a fixed-point decimal format where the integer part represents the number of seconds since a fixed reference point, and the fractional part represents fractions of a second.<br><br>The reference point is the epoch of NTP, which is January 1, 1900, at 00:00:00";
this.infoURL = "https://en.wikipedia.org/wiki/Network_Time_Protocol";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "Input: NTP timestamp format",
"type": "option",
"value": ["Fixed-point decimal", "Hex (big-endian)", "Hex (little-endian)"]
},
{
"name": "Output : Unix timestamp unit",
"type": "option",
"value": ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"]
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [format, unit] = args;
if (!input || input.trim().length === 0) {
return "";
} else {
input = new RemoveWhitespace().run(input, [true, true, true, true, true, false]);
}
let ntpTimestampSecondsPart;
let ntpTimestampFractionsPart;
if (format.startsWith("Hex")) {
if (input.length !== 16) {
return `Error: NTP Timestamp should be 64 bits long`;
}
if (format === "Hex (little-endian)") {
// Convert little-endian to big-endian
input = new SwapEndianness().run(input, ["Raw", input.length, false]);
}
// Getting the 32 bits (8 first hexa values) long seconds part
const hexNtpTimestampSecondsPart = input.substring(0, 8);
// Getting the 32 bits (8 last hexa values) long seconds fractions part
const hexNtpTimestampFractionsPart = input.substring(input.length - 8, input.length);
// Convert hexadecimal values to decimal values
ntpTimestampSecondsPart = new BigNumber(hexNtpTimestampSecondsPart, 16);
ntpTimestampFractionsPart = new BigNumber(hexNtpTimestampFractionsPart, 16);
} else if (format === "Fixed-point decimal") {
// Get the seconds and the seconds fractions parts of the timestamp separated by a "."
const pfNtpTimestampSecondsAndFractionsParts = String(input).split(".");
ntpTimestampSecondsPart = new Number(pfNtpTimestampSecondsAndFractionsParts[0]);
ntpTimestampFractionsPart = pfNtpTimestampSecondsAndFractionsParts[1];
if (ntpTimestampFractionsPart === null) {
ntpTimestampFractionsPart = 0;
} else {
ntpTimestampFractionsPart = new Number(pfNtpTimestampSecondsAndFractionsParts[1]);
}
} else {
throw new OperationError("Unrecognised format");
}
// Set the maximum unsigned positive integer representable in 32 bits
const maxUint32=new Number(Math.pow(2, 32));
// Check whether the seconds and the seconds fractions parts values do
// not exceeds the maximum positive integer representable in 32 bits
if (ntpTimestampSecondsPart > maxUint32) {
return `Error: Timestamp seconds part should be 32 bits long. The seconds part '${ntpTimestampSecondsPart}' of the provided NTP timestamp exceeds the maximum positive integer representable in 32 bits '${maxUint32}'`;
}
if (ntpTimestampFractionsPart > maxUint32) {
return `Error: Timestamp fractions seconds part should be 32 bits long. The fractions seconds part '${ntpTimestampFractionsPart}' of the provided NTP timestamp exceeds the maximum positive integer representable in 32 bits '${maxUint32}'`;
}
// Convert the NTP timestamp seconds part value (seconds elapsed since 01 january
// 1900 midnight) to UNIX timestamp (seconds elapsed since 01 january 1970 midnight)
const unixTimestampSecondsPart = ntpTimestampSecondsPart - new Number("2208988800");
// Convert the NTP timestamp seconds fractions part value to seconds
const unixTimestampFractionsPart = ntpTimestampFractionsPart / new Number(Math.pow(2, 32));
// Addition the seconds part value to the seconds fractions part value
// to form the UNIX timestamp in seconds
let unixTimestamp=unixTimestampSecondsPart + unixTimestampFractionsPart;
// Convert seconds Unix timestamp to requested result unit
if (unit === "Seconds (s)") {
return String(unixTimestamp);
} else if (unit === "Milliseconds (ms)") {
unixTimestamp = unixTimestamp * new Number("1000");
} else if (unit === "Microseconds (μs)") {
unixTimestamp = unixTimestamp * new Number(Math.pow(10, 6));
} else if (unit === "Nanoseconds (ns)") {
unixTimestamp = unixTimestamp * new Number(Math.pow(10, 9));
} else {
throw new OperationError("Unrecognised unit");
}
return String(unixTimestamp);
}
}
export default NTPTimestampToUNIXTimestamp;

View file

@ -0,0 +1,126 @@
/**
* @author kossithedon [kossivijunior@yahoo.fr]
* @copyright Crown Copyright 2024
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import RemoveWhitespace from "./RemoveWhitespace.mjs";
import SwapEndianness from "./SwapEndianness.mjs";
import OperationError from "../errors/OperationError.mjs";
/**
* UNIX Timestamp to NTP Timestamp operation
*/
class NTPTimestampToUNIXTimestamp extends Operation {
/**
* UNIXTimestampToNTPTimestamp constructor
*/
constructor() {
super();
this.name = "UNIX Timestamp to NTP Timestamp";
this.module = "Default";
this.description = "Convert an NTP timestamp to the corresponding UNIX timestamp.<br><br>An NTP timestamp is a 64-bit value representing time in the Network Time Protocol (NTP).<br><br>The NTP timestamp is in a fixed-point decimal format where the integer part represents the number of seconds since a fixed reference point, and the fractional part represents fractions of a second.<br><br>The reference point is the epoch of NTP, which is January 1, 1900, at 00:00:00";
this.infoURL = "https://en.wikipedia.org/wiki/Network_Time_Protocol";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "Input : Unix timestamp unit",
"type": "option",
"value": ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"]
},
{
"name": "Output: NTP timestamp format",
"type": "option",
"value": ["Fixed-point decimal", "Hex (big-endian)", "Hex (little-endian)"]
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [unit, format] = args;
if (!input || input.trim().length === 0) {
return "";
} else {
input = new RemoveWhitespace().run(input, [true, true, true, true, true, false]);
}
let unixTimestampSeconds;
// Convert the provided Unix timestmap to seconds Unix timestamps
if (unit === "Seconds (s)") {
unixTimestampSeconds = input;
} else if (unit === "Milliseconds (ms)") {
unixTimestampSeconds = input / new Number("1000");
} else if (unit === "Microseconds (μs)") {
unixTimestampSeconds = input / new Number(Math.pow(10, 6));
} else if (unit === "Nanoseconds (ns)") {
unixTimestampSeconds = input / new Number(Math.pow(10, 9));
} else {
throw new OperationError("Unrecognised unit");
}
// Get the seconds and the fractions seconds parts of the UNIX timestamp
const unixTimestampSecondsPart = Math.floor(unixTimestampSeconds);
const unixTimestampFractionsPart = unixTimestampSeconds % 1;
// The greatest seconds value is the maximum unsigned positive integer representable
// in 32 bits (2**32) - 2208988800 (seconds elapsed from NTP Epoch and UNIX Epoch)
const greatestSecondsValue = Math.pow(2, 32) - 2208988800;
// Check whether the seconds value part do not exceeds the greatest seconds value
if (unixTimestampSecondsPart > greatestSecondsValue) {
return `Error: The NTP Timestamp seconds part '${unixTimestampSecondsPart}' exceeds the greatest authorized seconds value '${greatestSecondsValue}' due to an incorrect provided UNIX timestamp`;
}
// Convert the UNIX timestamp seconds part value (seconds elapsed since 01 january
// 1970 midnight) to NTP timestamp (seconds elapsed since 01 january 1900 midnight)
const ntpTimestampSecondsPart = unixTimestampSecondsPart + new Number("2208988800");
// Convert the NTP timestamp seconds fractions part value to seconds
const ntpTimestampFractionsPart = unixTimestampFractionsPart * (Math.pow(2, 32));
if (format.startsWith("Hex")) {
// Convert Unix timestamp seconds and seconds fractions parts from decimal to hexadecimal
const hexNtpTimestampSecondsPart = ntpTimestampSecondsPart.toString(16);
let hexNtptimestampfractionsPart = ntpTimestampFractionsPart.toString(16);
if (hexNtptimestampfractionsPart === 0) {
// pad hexadecimal seconds fractions part
hexNtptimestampfractionsPart = "00000000";
}
// Concatenate seconds part hexadecimal value to seconds fractions part
// hexadecimal value to form the big-endian hexadecimal Unix timestamp
const beHexNtpTimestamp = hexNtpTimestampSecondsPart + hexNtptimestampfractionsPart;
if (format === "Hex (little-endian)") {
// Convert big-endian to little-endian
const leHexNtpTimestamp = new SwapEndianness().run(beHexNtpTimestamp, ["Raw", 16, false]);
return leHexNtpTimestamp;
} else if (format === "Hex (big-endian)") {
return beHexNtpTimestamp;
} else {
throw new OperationError("Unrecognised format");
}
} else if (format === "Fixed-point decimal") {
// Construct the NTP timestamp by concatenating the seconds part
// value to the seconds fractions part value separeted by a "."
const pfNtpTimestamp=ntpTimestampSecondsPart+"."+ntpTimestampFractionsPart;
return pfNtpTimestamp;
} else {
throw new OperationError("Unrecognised format");
}
}
}
export default NTPTimestampToUNIXTimestamp;

View file

@ -176,6 +176,8 @@ import "./tests/JSONtoYAML.mjs";
import "./tests/YARA.mjs"; import "./tests/YARA.mjs";
import "./tests/ParseCSR.mjs"; import "./tests/ParseCSR.mjs";
import "./tests/XXTEA.mjs"; import "./tests/XXTEA.mjs";
import "./tests/NTPTimestampToUNIXTimestamp.mjs";
import "./tests/UNIXTimestampToNTPTimestamp.mjs";
const testStatus = { const testStatus = {
allTestsPassing: true, allTestsPassing: true,

View file

@ -0,0 +1,211 @@
/**
* Set NTP timestamp to UNIX timestamp tests.
*
* @author kossithedon
*
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "Fixed-point decimal NTP Timestamp to Seconds UNIX Timestamp",
input: "3923215437.1842400034",
expectedOutput: "1714226637.4289672",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Fixed-point decimal", "Seconds (s)"],
},
],
},
{
name: "Fixed-point decimal NTP Timestamp to Milliseconds UNIX Timestamp",
input: "3923215437.1842400034",
expectedOutput: "1714226637428.9673",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Fixed-point decimal", "Milliseconds (ms)"],
},
],
},
{
name: "Fixed-point decimal NTP Timestamp to Microseconds UNIX Timestamp",
input: "3923215437.1842400034",
expectedOutput: "1714226637428967.2",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Fixed-point decimal", "Microseconds (μs)"],
},
],
},
{
name: "Fixed-point decimal NTP Timestamp to Nanoseconds UNIX Timestamp",
input: "3923215437.1842400034",
expectedOutput: "1714226637428967200",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Fixed-point decimal", "Nanoseconds (ns)"],
},
],
},
{
name: "Big-endian hexadecimal NTP Timestamp to Seconds UNIX Timestamp",
input: "e9d784613df8dd8b",
expectedOutput: "1714226657.2420785",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (big-endian)", "Seconds (s)"],
},
],
},
{
name: "Big-endian hexadecimal NTP Timestamp to Milliseconds UNIX Timestamp",
input: "e9d784613df8dd8b",
expectedOutput: "1714226657242.0786",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (big-endian)", "Milliseconds (ms)"],
},
],
},
{
name: "Big-endian hexadecimal NTP Timestamp to Microseconds UNIX Timestamp",
input: "e9d784613df8dd8b",
expectedOutput: "1714226657242078.5",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (big-endian)", "Microseconds (μs)"],
},
],
},
{
name: "Big-endian hexadecimal NTP Timestamp to Nanoseconds UNIX Timestamp",
input: "e9d784613df8dd8b",
expectedOutput: "1714226657242078500",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (big-endian)", "Nanoseconds (ns)"],
},
],
},
{
name: "Little-endian hexadecimal NTP Timestamp to Seconds UNIX Timestamp",
input: "b8dd8fd316487d9e",
expectedOutput: "1714226657.2420785",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (little-endian)", "Seconds (s)"],
},
],
},
{
name: "Little-endian hexadecimal NTP Timestamp to Milliseconds UNIX Timestamp",
input: "b8dd8fd316487d9e",
expectedOutput: "1714226657242.0786",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (little-endian)", "Milliseconds (ms)"],
},
],
},
{
name: "Little-endian hexadecimal NTP Timestamp to Microseconds UNIX Timestamp",
input: "b8dd8fd316487d9e",
expectedOutput: "1714226657242078.5",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (little-endian)", "Microseconds (μs)"],
},
],
},
{
name: "Little-endian hexadecimal NTP Timestamp to Nanoseconds UNIX Timestamp",
input: "b8dd8fd316487d9e",
expectedOutput: "1714226657242078500",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (little-endian)", "Nanoseconds (ns)"],
},
],
},
{
name: "Hexadecimal NTP Timestamp to UNIX Timestamp : too long hexadecimal NTP timestamp input",
input: "e9d784613df8dd8bf",
expectedOutput: "Error: NTP Timestamp should be 64 bits long",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (big-endian)", "Seconds (s)"],
},
],
},
{
name: "Hexadecimal NTP Timestamp to UNIX Timestamp : too short hexadecimal NTP timestamp input",
input: "b8dd8fd316487d9",
expectedOutput: "Error: NTP Timestamp should be 64 bits long",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Hex (little-endian)", "Seconds (s)"],
},
],
},
{
name: "NTP Timestamp to UNIX Timestamp : NTP Timestamp input unrecognised format",
input: "60954b2d-7151-45c7-99cc-aca4ab664a8e",
expectedOutput: "Unrecognised format",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["uuid", "Seconds (s)"],
},
],
},
{
name: "NTP Timestamp to UNIX Timestamp : UNIX Timestamp output unrecognised unit",
input: "3923215437.1842400034",
expectedOutput: "Unrecognised unit",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Fixed-point decimal", "Hours"],
},
],
},
{
name: "NTP Timestamp to UNIX Timestamp : NTP timestamp seconds part is greater than the greatest 32 bits value 4294967296",
input: "4294967297.1842400034",
expectedOutput: "Error: Timestamp seconds part should be 32 bits long. The seconds part '4294967297' of the provided NTP timestamp exceeds the maximum positive integer representable in 32 bits '4294967296'",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Fixed-point decimal", "Seconds (s)"],
},
],
},
{
name: "NTP Timestamp to UNIX Timestamp : NTP timestamp seconds fractions part is greater than the greatest 32 bits value 4294967296",
input: "3923215437.4294967297",
expectedOutput: "Error: Timestamp fractions seconds part should be 32 bits long. The fractions seconds part '4294967297' of the provided NTP timestamp exceeds the maximum positive integer representable in 32 bits '4294967296'",
recipeConfig: [
{
op: "NTP Timestamp to UNIX Timestamp",
args: ["Fixed-point decimal", "Seconds (s)"],
},
],
}
]);

View file

@ -0,0 +1,178 @@
/**
* Set UNIX Timestamp to NTP Timestamp tests.
*
* @author kossithedon
*
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "Seconds UNIX Timestamp to Fixed-point decimal NTP Timestamp",
input: "1714226657.2420785",
expectedOutput: "3923215457.1039719424",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Seconds (s)", "Fixed-point decimal"],
},
],
},
{
name: "Milliseconds UNIX Timestamp to Fixed-point decimal NTP Timestamp ",
input: "1714226657242.0786",
expectedOutput: "3923215457.1039719424",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Milliseconds (ms)", "Fixed-point decimal"],
},
],
},
{
name: "Microseconds UNIX Timestamp to Fixed-point decimal NTP Timestamp ",
input: "1714226657242078.5",
expectedOutput: "3923215457.1039719424",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Microseconds (μs)", "Fixed-point decimal"],
},
],
},
{
name: "Nanoseconds UNIX Timestamp to Fixed-point decimal NTP Timestamp",
input: "1714226657242078500",
expectedOutput: "3923215457.1039719424",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Nanoseconds (ns)", "Fixed-point decimal"],
},
],
},
{
name: "Seconds UNIX Timestamp to Big-endian hexadecimal NTP Timestamp",
input: "1714226657.2420785",
expectedOutput: "e9d784613df8dc00",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Seconds (s)", "Hex (big-endian)"],
},
],
},
{
name: "Milliseconds UNIX Timestamp to Big-endian hexadecimal NTP Timestamp",
input: "1714226657242.0786",
expectedOutput: "e9d784613df8dc00",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Milliseconds (ms)", "Hex (big-endian)"],
},
],
},
{
name: "Microseconds UNIX Timestamp to Big-endian hexadecimal NTP Timestamp",
input: "1714226657242078.5",
expectedOutput: "e9d784613df8dc00",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Microseconds (μs)", "Hex (big-endian)"],
},
],
},
{
name: "Nanoseconds UNIX Timestamp to Big-endian hexadecimal NTP Timestamp",
input: "1714226657242078500",
expectedOutput: "e9d784613df8dc00",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Nanoseconds (ns)", "Hex (big-endian)"],
},
],
},
{
name: "Seconds UNIX Timestamp to Little-endian hexadecimal NTP Timestamp",
input: "1714226657.2420785",
expectedOutput: "00cd8fd316487d9e",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Seconds (s)", "Hex (little-endian)"],
},
],
},
{
name: "Milliseconds UNIX Timestamp to Little-endian hexadecimal NTP Timestamp",
input: "1714226657242.0786",
expectedOutput: "00cd8fd316487d9e",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Milliseconds (ms)", "Hex (little-endian)"],
},
],
},
{
name: "Microseconds UNIX Timestamp to Little-endian hexadecimal NTP Timestamp",
input: "1714226657242078.5",
expectedOutput: "00cd8fd316487d9e",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Microseconds (μs)", "Hex (little-endian)"],
},
],
},
{
name: "Nanoseconds UNIX Timestamp to Little-endian hexadecimal NTP Timestamp",
input: "1714226657242078500",
expectedOutput: "00cd8fd316487d9e",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Nanoseconds (ns)", "Hex (little-endian)"],
},
],
},
{
name: "UNIX Timestamp to NTP Timestamp : UNIX Timestamp input unrecognised format",
input: "60954b2d-7151-45c7-99cc-aca4ab664a8e",
expectedOutput: "Unrecognised unit",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["uuid", "Fixed-point decimal"],
},
],
},
{
name: "UNIX Timestamp to NTP Timestamp : UNIX Timestamp output unrecognised format",
input: "1714226657.2420785",
expectedOutput: "Unrecognised format",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Seconds (s)", "Floating-point"],
},
],
},
{
name: "UNIX Timestamp to NTP Timestamp : NTP timestamp seconds part is greater than the greatest authorized value 2085978496",
input: "2085978497",
expectedOutput: "Error: The NTP Timestamp seconds part '2085978497' exceeds the greatest authorized seconds value '2085978496' due to an incorrect provided UNIX timestamp",
recipeConfig: [
{
op: "UNIX Timestamp to NTP Timestamp",
args: ["Seconds (s)", "Fixed-point decimal"],
},
],
}
]);