mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 14:56:19 -04:00
126 lines
5.6 KiB
JavaScript
Executable file
126 lines
5.6 KiB
JavaScript
Executable file
/**
|
|
* @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;
|