2018-04-02 19:06:48 +02:00
|
|
|
/**
|
2018-08-19 23:50:49 +02:00
|
|
|
* Hexadecimal functions.
|
2018-04-02 19:06:48 +02:00
|
|
|
*
|
|
|
|
* @author n1474335 [n1474335@gmail.com]
|
|
|
|
* @copyright Crown Copyright 2016
|
|
|
|
* @license Apache-2.0
|
|
|
|
*/
|
|
|
|
|
2019-07-09 13:23:59 +02:00
|
|
|
import Utils from "../Utils.mjs";
|
2018-04-02 19:06:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a byte array into a hex string.
|
|
|
|
*
|
2019-07-03 18:23:45 +02:00
|
|
|
* @param {byteArray|Uint8Array|ArrayBuffer} data
|
2018-04-02 19:06:48 +02:00
|
|
|
* @param {string} [delim=" "]
|
|
|
|
* @param {number} [padding=2]
|
|
|
|
* @returns {string}
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
* // returns "0a 14 1e"
|
|
|
|
* toHex([10,20,30]);
|
|
|
|
*
|
|
|
|
* // returns "0a:14:1e"
|
|
|
|
* toHex([10,20,30], ":");
|
2020-01-15 01:14:43 +01:00
|
|
|
*
|
|
|
|
* // returns "0x0a,0x14,0x1e"
|
|
|
|
* toHex([10,20,30], "0x", 2, ",")
|
2018-04-02 19:06:48 +02:00
|
|
|
*/
|
2020-01-15 01:14:43 +01:00
|
|
|
export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) {
|
2018-04-02 19:06:48 +02:00
|
|
|
if (!data) return "";
|
2019-07-03 18:23:45 +02:00
|
|
|
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
2018-04-02 19:06:48 +02:00
|
|
|
|
|
|
|
let output = "";
|
2020-01-15 01:14:43 +01:00
|
|
|
const prepend = (delim === "0x" || delim === "\\x");
|
2018-04-02 19:06:48 +02:00
|
|
|
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
2020-01-15 01:14:43 +01:00
|
|
|
const hex = data[i].toString(16).padStart(padding, "0");
|
|
|
|
if (prepend) {
|
|
|
|
output += delim + hex;
|
|
|
|
} else {
|
|
|
|
output += hex + delim;
|
|
|
|
}
|
|
|
|
if (extraDelim) {
|
|
|
|
output += extraDelim;
|
|
|
|
}
|
|
|
|
// Add LF after each lineSize amount of bytes but not at the end
|
|
|
|
if ((i !== data.length - 1) && ((i + 1) % lineSize === 0)) {
|
|
|
|
output += "\n";
|
|
|
|
}
|
2018-04-02 19:06:48 +02:00
|
|
|
}
|
|
|
|
|
2020-01-15 01:14:43 +01:00
|
|
|
// Remove the extraDelim at the end (if there is);
|
|
|
|
// and remove the delim at the end, but if it's prepended there's nothing to remove
|
|
|
|
const rTruncLen = extraDelim.length + (prepend ? 0 : delim.length);
|
|
|
|
if (rTruncLen) {
|
|
|
|
// If rTruncLen === 0 then output.slice(0,0) will be returned, which is nothing
|
|
|
|
return output.slice(0, -rTruncLen);
|
|
|
|
} else {
|
2018-04-02 19:06:48 +02:00
|
|
|
return output;
|
2020-01-15 01:14:43 +01:00
|
|
|
}
|
2018-04-02 19:06:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a byte array into a hex string as efficiently as possible with no options.
|
|
|
|
*
|
2019-07-03 18:23:45 +02:00
|
|
|
* @param {byteArray|Uint8Array|ArrayBuffer} data
|
2018-04-02 19:06:48 +02:00
|
|
|
* @returns {string}
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
* // returns "0a141e"
|
|
|
|
* toHex([10,20,30]);
|
|
|
|
*/
|
|
|
|
export function toHexFast(data) {
|
|
|
|
if (!data) return "";
|
2019-07-03 18:23:45 +02:00
|
|
|
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
2018-04-02 19:06:48 +02:00
|
|
|
|
|
|
|
const output = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
|
|
output.push((data[i] >>> 4).toString(16));
|
|
|
|
output.push((data[i] & 0x0f).toString(16));
|
|
|
|
}
|
|
|
|
|
|
|
|
return output.join("");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a hex string into a byte array.
|
|
|
|
*
|
|
|
|
* @param {string} data
|
|
|
|
* @param {string} [delim]
|
|
|
|
* @param {number} [byteLen=2]
|
|
|
|
* @returns {byteArray}
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
* // returns [10,20,30]
|
|
|
|
* fromHex("0a 14 1e");
|
|
|
|
*
|
|
|
|
* // returns [10,20,30]
|
|
|
|
* fromHex("0a:14:1e", "Colon");
|
|
|
|
*/
|
2018-08-19 23:50:49 +02:00
|
|
|
export function fromHex(data, delim="Auto", byteLen=2) {
|
2018-04-02 19:06:48 +02:00
|
|
|
if (delim !== "None") {
|
2020-01-15 23:20:47 +01:00
|
|
|
const delimRegex = delim === "Auto" ? /[^a-f\d]|(0x)/gi : Utils.regexRep(delim);
|
2018-04-02 19:06:48 +02:00
|
|
|
data = data.replace(delimRegex, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
const output = [];
|
|
|
|
for (let i = 0; i < data.length; i += byteLen) {
|
|
|
|
output.push(parseInt(data.substr(i, byteLen), 16));
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2018-05-14 13:58:01 +02:00
|
|
|
* To Hexadecimal delimiters.
|
2018-04-02 19:06:48 +02:00
|
|
|
*/
|
2019-03-22 01:10:45 +01:00
|
|
|
export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"];
|
2018-05-14 13:58:01 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* From Hexadecimal delimiters.
|
|
|
|
*/
|
|
|
|
export const FROM_HEX_DELIM_OPTIONS = ["Auto"].concat(TO_HEX_DELIM_OPTIONS);
|